Add Comment
Parsing XML Tutorial
ColdFusion Tutorial #18
There are many, many uses for XML, and if you use ColdFusion to consume web services, or create data integration processes, then chances are, you will need to work with XML. As of ColdFusion MX there are several tags and functions that make working with XML a snap. In this tutorial I am going to focus on teaching you how to pull the information you need out of XML documents.
demo.cfm
There are several methods you might use to read the XML text into a ColdFusion variable. These methods depend on the source of the XML. If it's in a database you would use CFQUERY, if it is on a file on the ColdFusion server you would read it with CFILE, if you are downloading it from the web you could use CFHTTP or CFFTP, etc. Ultimately, you will end up with a ColdFusion variable that contains the XML text. For this example, and just to keep it simple, I am going to use CFSAVECONTENT to create that variable. This is done on lines 1-20.As you can see, we are going to work with XML that contains a list of books. The first thing we need to do is use XMLParse() to convert the text contained in the "XMLFile" variable into a ColdFusion XML document object. An XML document object is how ColdFusion represents an XML document, and is much like a ColdFusion structure. This is done on line 23.
In the first example we will simply dump the parsed XML, lines 26-27.
Now you are at the point where you can start pulling the data that you need out of the XML. The best way to pull the information you need out of a ColdFusion XML document object is to use the XMLSearch() function. XMLSearch uses an XPath language expression to search an XML document object and returns a ColdFusion array containing the matching nodes. XPath is a language for addressing parts of an XML document, and the expressions are pretty easy to write once you spend a little time figuring them out.
The basic XPath syntax is similar to file system addressing. If the path starts with a "/", then it represents an absolute path to the element you want.
So if we want to get all the "book" nodes from our XML we could use the example on lines 29-40.
If the path starts with "//" then all elements in the document which fulfill criteria following the "//" are selected. So, if we just wanted to pull a list of authors from our XML, we could use the example on lines 42-50.
With more advanced XPath expressions you can do things like search for nodes with specific values. Here is an example of how to find all the books with titles that contain "ColdFusion". (Keep in mind that these contains() searches are case sensitive.), the example is on lines 52-62.
There are many other ways you can use XMLSearch and XPath to pull the data you need from your XML. To learn more about them visit www.w3.org/TR/xpath/, or just search Google for "XPath Tutorial" and you will find several good ones.
Demo
See this code running!
Download
Download this code as a zip!
Comments
Using your book XML example from above. Say that the returned XML only *sometimes* contained the <author> field of data. When looping and outputting the results, an error would occur. How can this be remedied? A solution w/o a cftry/cfcatch block would be great!Viper @ Tuesday 04 Dec 2007 - 03:59:24 AM
I believe you can just do an if using structKeyExists
Dale Fraser @ Tuesday 04 Dec 2007 - 10:34:14 AM
Hi,
Great tutorial, helped me get my feet wet with CF and XML. I was wondering if someone may help me though. I am new to CF, and when going through your tutorial i substituted my own XML and get the error:
The prefix "xlink" for attribute "xlink:href" associated with an element type "Order" is not bound.
my xml looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<Response success="true" xmlns:xlink="http://www.w3.org/1999/xlink">
<Orders>
<Order xlink:href="http://localhost/API/80086/Orders/173468288">173468288</Order>
<Order xlink:href="http://localhost/API/80086/Orders/173468285">173468285</Order>
<Order xlink:href="http://localhost/API/80086/Orders/173468225">173468225</Order>
</Orders>
</Response>
Thanks,
Chris.
Chris @ Tuesday 06 May 2008 - 11:27:44 PM
I would do it like this:
<cfsavecontent variable="XMLFile">
<Response success="true" xmlns:xlink="http://www.w3.org/1999/xlink">
<Orders>
<Order xlink:href="http://localhost/API/80086/Orders/173468288">173468288</Order>
<Order xlink:href="http://localhost/API/80086/Orders/173468285">173468285</Order>
<Order xlink:href="http://localhost/API/80086/Orders/173468225">173468225</Order>
</Orders>
</Response>
</cfsavecontent>
<cfset MyXMLDoc = xmlParse(XMLFile)>
<cfset OrderNodes = xmlSearch(MyXMLDoc,"/Response/Orders/Order")>
<cfoutput>
<cfloop from="1" to="#arraylen(OrderNodes)#" index="i">
order = #OrderNodes[i].XmlText#
HREF = #OrderNodes[i].XmlAttributes['xlink:href']#
</cfloop>
</cfoutput>
Scott Bennett @ Wednesday 07 May 2008 - 05:47:16 AM
Click button to add a comment
Author
Scott Bennett
Published
Friday 16 Nov 2007Original
This tutorial has been modified and published with permission of the author. The original tutorial can be found herehttp://www.coldfusionguy.com/ColdFusion/blog/index.cfm/2007/11/15/ColdFusion-Tutorial-Reading-XML-Documents