Using XML feeds with Coldfusion MX

Macromedia's latest version of Coldfusion, Coldfusion MX (CFMX) makes it even easier than ever to
use other people's syndicated content on your website. With its new XML functions it can quickly parse
an XML document which you can step through and output to an HTML page as easily as if it were a
recordset from a database. To jump straight to the raw code that I used to simply output a feed's individual
items then click here

Step 1: Getting the XML feed

If you've used Coldfusion before then no doubt at some point you'll have come across the <cfhttp> tag.
If not, don't worry. Its a tag that performs an HTTP GET or POST operation from the server, so that
you can perform actions on other websites and collect the resulting output. Here we use it to collect a
feed that we've discovered on Syndic8 or another feed aggregator. Here's the code:

<cfhttp url="http://www.funjunkie.co.uk/news.xml"
method="GET"
resolveUrl="false">

Here I'm getting the xml feed produced by this website. So that was pretty easy, but here comes the
more complex bit:

Step 2: Transforming into an XML object

Here we're using CFMX's new XML functions to tranform what at this point the server regards as a long
text string into a useable and structured XML document object. We use the XMLParse() function,
which accepts a string and attempts to convert it into the XML. Obviously a non-valid xml feed will choke
at this point, and you'll receive an error message telling you why. Assuming the feed is valid though, here's
the code:

<cfset myXMLDoc = XMLParse(cfhttp.filecontent)>

we set a new variable, myXMLDoc, to contain the results of the XMLParse() function. The target of the
function is the variable cfhttp.filecontent, which contains the results of any <cfhttp> call.
The XMLParse() function transforms the string into the XML document object for us to use. At this
stage you can use:

<cfdump var="#myXMLDoc#">

which will output a representation of the entire document in HTML for you to check that you've got what
you expected.

Step 3: Getting what we want from the XML object

So now we've got a valid XML object, how do we use it? Well CFMX comes with a number of XML functions
such as XmlElemNew(), XmlChildPos(), XmlTransform() which we can use to alter the document, but for now we
just want to format some of its contents in HTML. In this instance I want to just output each item in my
XML document. We can use the function XMLSearch() to retrieve just these elements. Here's the code:

<cfset myItems = XMLSearch(myXMLDoc, "/rss/channel/item")>

XMLSearch takes two values, the first of which is the name of the variable containing your XML object, and the
second is a valid XPath language expression. You can read more about XPath at http://www.w3.org/TR/xpath, but
for now, lets describe it as if we were accessing directories on a filesystem. You begin at the top "/rss" and then traverse
down through the directories until you get to the directory containing the information you want. Note: your XML file
may be quite different and not follow the same structure that I've used here, make sure you use <cfdump> and get
a representation of your XML structure before you start.

Step 4: Outputting to HTML

Now we've got just those elements of the XML object that we were interested in, we can do whatever we like with them.
Here, I'm just going to simply output them in HTML, separated by <hr> elements.

<cfloop from="1" to="#arrayLen(myItems)#" index="i">
<cfoutput><a href="#myItems[i].link.xmltext#">#myItems[i].title.xmltext#</a><br>
#myItems[i].description.xmltext#</cfoutput><hr>
</cfloop>

When we perform an XMLSearch() function like we did above, any results are placed in an array that we here called "myItems".
The actual value of the elements that we want are placed in a structure according to this format:

myItems[arrayindex].<ElementName>.xmlText

where <ElementName> is the name of the element whose attributes you wish to use. We use arrayLen(myTitles) to
get the length of the array and then loop over that array, outputting the elements we want. And here's my resulting content
(from the news page on funjunkie.co.uk).

I blame Mike Williams
Ahh, weddings. Time to let down you hair, do some dancing, smoke some cigars, and inflate your tongue.
Pucking Hell
It comes to something when you go to a real Ice Hockey match and start trying to press 'X' to lamp the bastard who just intercepted your team's pass!Come on Vipers, get it together...

The Final Code

Here's all the code for the above:

<cfhttp url="http://www.funjunkie.co.uk/news.xml"
method="GET"
resolveUrl="false">


<cfset myXMLDoc = XMLParse(cfhttp.filecontent)>

<cfset myItems = XMLSearch(myXMLDoc, "/rss/channel/item")>

<cfloop from="1" to="#arrayLen(myItems)#" index="i">
<cfoutput><a href="#myItems[i].link.xmltext#">#myItems[i].title.xmltext#</a><br>
#myItems[i].description.xmltext#</cfoutput><hr>
</cfloop>

And thats it! For best performance, try scheduling this task and writing the resulting output to a file at a set time interval. Then
simply include that file into your pages.

Author:
Rich Wild, code monkey for Funjunkie (http://www.funjunkie.co.uk). Any comments/alterations on this document,
please contact me at richwild@(nospam)funjunkie.co.uk.