How to read in data from an XML file

This lesson will show you how to load an XML file and access the data for use in your application. XML files are a very useful for things like storing preference settings, working with the web and for situations where you need to share data with other programs.

LiveCode provides a well-featured library for dealing with XML files, which can take a little getting used to but is quite straight forward to use.

Create a stack with a button and a field

We start by creating a stack and dragging a button and a field onto it. The button will contain our LiveCode code for reading the XML file. The field will contain the resulting data that is read from the file, set the name of the field to "information". Save this stack on your desktop.

Create an XML file to use as an example

Create an XML file to use as an example

Use Notepad on Windows or TextEdit on Mac OS X to create the example preferences XML file. The file should be plain text. Save the file on your desktop as "Preferences.xml". The XML data looks like this:

<preferences>

 <textColor>blue</textColor>

 <textSize>16</textSize>

 <introMessage size="18">Welcome guest, please click the button below to log in</introMessage>

 <recentDocuments>

   <recentDocument>C:/Documents and Settings/Administrator/Documents/DraftReport.txt</recentDocument>

   <recentDocument>C:/Reports/2009Final.txt</recentDocument>

   <recentDocument>C:/Documents and Settings/Administrator/Desktop/Temp.txt</recentDocument>

 </recentDocuments>

</preferences>

Tell the button to load the file when the user clicks

Edit the script of the button by selecting it, then clicking on the "Script" button in the main menu bar. For this example we are going to load an XML file that contains preferences for our application.

Begin the script with the following code:

1. When the button is clicked, load up the preferences and put them into the field

on mouseUp
    loadPreferences
 end mouseUp

2. Load the preferences file

There are two parts to loading the preferences file. The first part is reading the file into memory and creating an XML "tree". The second part is to process the tree and extract the data from it.

This function reads the XML file, and returns the tree. The tree is represented as a number, the actual tree structure and data is managed by LiveCode and so we don't need to worry about it.

command loadPreferences
local tTree
put readPreferencesToXMLTree() into tTree
if tTree is empty then
exit loadPreferences
end if

# Read the preferences we require from the tree and display them.
processPreferencesTree tTree

# Close the XML tree. 
   # This will free up the memory that the tree was using and prevent our application
# using more memory than it needs or "leaking" memory by creating multiple trees
# without closing any of them.
revXMLDeleteTree tTree
end loadPreferences

Note that this code doesn't do anything just yet, because we haven't yet implemented the function readPreferencesToXMLTree and the command processPreferencesTree.

Read the XML file from disk

Next, we implement a function to read the XML. This is done in two steps, first the file is read into a variable like any other text file would be, secondly, an XML "tree" is created from the file. This tree allows us to manipulate the XML data easily.

Add the code to read the XML file as below.

private function readPreferencesToXMLTree
	# Find the XML file on disk. 
   # This is for now assumed to be in the same location as the stack / application.
	# Note that we restore the itemDelimiter to comma (its default value) afterwards.           	
	# This is not essential but its good practice to avoid tricky bugs 
   # that can arise due to unexpected delimiter values.
	set the itemDelimiter to slash
	local tPreferencesFile
	put item 1 to -2 of the effective filename of this stack & "/Preferences.xml" into tPreferencesFile
	set the itemDelimiter to comma
	
	# Read the preferences data from the file into a variable. 
   # Always check for the result when reading files
	# as its possible that the file may have been deleted or moved.
	local tPreferencesData, tResult
	put url ("file:" & tPreferencesFile) into tPreferencesData
	put the result into tResult
	if tResult is not empty then
		answer error "Failed to read preferences file at location: " & tPreferencesFile
		return empty
	end if
	
	# Create the XML "tree" from the data, 
   # checking to make sure that the file has loaded properly.
	# The revCreateXMLTree function will return a number 
   # (the tree's "handle" or "id") if it succeeds,
	# otherwise it will return a message saying why it failed.
	local tTree
	put revXMLCreateTree(tPreferencesData, false, true, false) into tTree
	if tTree is not an integer then
		answer error "Failed to process preferences file with error: " & tTree
		return empty
	end if
	
	return tTree
end readPreferencesToXMLTree

Extract the information out of the XML file and display it in a field

Once we have the XML tree, the final step is to use LiveCode's XML library to get the required information out of it. We use a series of calls to the XML library to extract each piece of information from the tree.

private command processPreferencesTree pTree
	# Extract the text color and text size preferences. 
	# These are simple nodes in the XML file,
	# we can get what is inside them using the revXMLNodeContents function
	# This function will return a string beginning with "xmlerr," 
	# if it fails, but we don't check this 
	# here as we created the file and we know it won't fail.
	local tTextColor
	put revXMLNodeContents(pTree, "preferences/textColor") into tTextColor
	
	local tTextSize
	put revXMLNodeContents(pTree, "preferences/textSize") into tTextSize
	
	# Extract the introductory message preference. 
	# This node has an attribute. We extract the contents and the 
	# attribute in two separate calls. 
	# The function revXMLAttribute allows us to read attributes from XML files,
	# its exactly the same as revXMLNodeContents, 
	# except that you also need to tell it which attribute you want.
	local tIntroMessage
	put revXMLNodeContents(pTree, "preferences/introMessage") into tIntroMessage
	
	local tIntroMessageSize
	put revXMLAttribute(pTree, "preferences/introMessage", "size") into tIntroMessageSize
	
	# Extract the recent documents list. 
	# This is a nested list of nodes, which could have any number of items.
	# First, we get a list of the recent documents, then we can loop 
	# through them and get each one in turn.
	# The revXMLChildNames function is useful for returning a list of nodes like this.  
	# The last parameter is important as it tells the function to return a unique
	# specifier for each node, allowing us to access them correctly. This will
	# look something like:
	#	recentDocument[1]
	#	recentDocument[2]
	#	recentDocument[3]
	local tRecentDocuments
	put revXMLChildNames(pTree, "preferences/recentDocuments", return, "recentDocument", true) into tRecentDocuments
	
	# To get each document, we just use revXMLNodeContents again. 
	# However here we concatentate the name of each node
	# with the path that all recent document nodes have in common, 
	# to get the complete path.
	local tListOfRecentDocuments
	repeat for each line tRecentDocument in tRecentDocuments
		put revXMLNodeContents(pTree, "preferences/recentDocuments/" & tRecentDocument) & return after tListOfRecentDocuments
	end repeat
	delete the last char of tListOfRecentDocuments
	
	# Now we output what we read from the file to see if it worked.
	local tOutput
	put "Text Color = " & tTextColor & return after tOutput
	put "Text Size = " & tTextSize & return after tOutput
	put return after tOutput
	put "Introductory Message (size: " & tIntroMessageSize & ") = " & return after tOutput
	put tIntroMessage & return & return after tOutput
	put "Recent Documents = " & return after tOutput
	put tListOfRecentDocuments after tOutput
	set the text of field "Information" to tOutput
end processPreferencesTree

Testing

To test the stack switch to Run mode and click the button.

9 Comments

Jay Anthony Nunez

Well done demonstration. :-)

Glenn

Well I did it, but there was no change to the font size nor color.

Hanson Schmidt-Cornelius

Hi Glenn,

this lesson describes how to load the content of an XML file and access the data. The data loaded is displayed in the "Information" field but is not applied in this lesson.

If you wish to apply the values loaded, then you would have to implement this as a next step.

Kind Regards,

Hanson

gary

What about actual XML files that commence with eg

How do you recommend going about deconstructing these?

Thanks in advance.

Hanson Schmidt-Cornelius

Hi Gary,

if there is content in the XML file that you think should not be in there when you process it, then you can remove that data first. Use the search and replace functionality within LiveCode to remove any characters or text that you think should not be present. You can do this because XML files are text files.
You can then process the XML data as you require.

Kind Regards,

Hanson

gary

Hi Hanson,

Thanks for your reply. That is what I have been doing, but wasn't sure if it was the correct way to go about it. I don't know why the code I copied over does not appear above but it was tags about xml and soap, and it is these that I have removed and replaced (at both ends of the document) with my own root node.

Gary

Gilar

i have succes to create an XML file, but it's an ANSI when i check in notepad
Now I need to create a unicode XML file
Could you please to explain how to do this

Thanks

Daniel

In LC 7 and following, the name of the function is not revCreateXMLTree but revXMLCreateTree; the parameters remain the same

Elanor Buchanan

Hi Daniel. Thanks for pointing that out, I have updated the lesson with the correction. Elanor

Add your comment

E-Mail me when someone replies to this comment