At last nights OCCFUG meeting, one of the members asked what is the best way to access the data from nodes in an XML document that have xmlns namespace prefixes. I touched on this topic briefly in the comments of my post about reading XML documents, but I thought I would expound upon it a little more as there doesn't seem to be a lot of solid explanations out there on how to do this in ColdFusion. In a nutshell, the answer is to use XMLSearch() with an xPath expression that utilizes the namespace-uri() function.
For this example we are going to use CFFEED to retrieve weather information from the Yahoo! weather api.
The myXml variable now contains the following xml:
You can see in that xml that there is a "geo" namespace that is used for the latitude and longitude nodes, and there is a namespace called "yweather" that is used in the nodes that hold the current and forecasted weather conditions. XML spaces always have a Uniform Resource Identifier (URI) associated with them, and the URI looks just like a URL that you would use to browse to a web page. You will need to use this URI in your xPath expression in order to find any node that has a namespace prefix.
This example shows how to write an xPath expression to find all the nodes with a specific namespace URI, and how to find nodes within a namespace that have a specific local name. (click here to see the results of this code)
From there you would just loop through the array of nodes that gets returned by the xmlSearch() function and do whatever you need to with the data. The following example outputs all the data from the yweather:forecast nodes (click here to see the results of this page):
XMLSearch() rocks! I remember before it arrived in ColdFusion MX and I would have to do all kinds of nested cfloops to get at nodes that were deep in an xml document. It's a big time saver once you learn how to write the xPath expressions. To learn more about them, visit http://www.w3.org/TR/xpath.
[cfset forecasts = XMLSearch(myXML, "//yweather:forecasts"/]
(note: this doesn't work with the sample xml above unless you move the xmlns:yweather decleration to the root element)