XMLSearch - No Results Found / Empty Array Solution

Just a quick post while it's fresh on my mind as I'm sure this is going to crop up in the future as I don't often handle XML in Coldfusion.

Basically here is the scenario. You have an XML file which isn't that complicated in structure but whatever you do XMLSearch just won't return the results you expect - it appears broken.

Here is an example from the Spotify API:

<?xml version="1.0" encoding="utf-8"?>
<artists xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/" xmlns="http://www.spotify.com/ns/music/1">     
     <opensearch:Query role="request" startPage="1" searchTerms="Ash"/>
     <opensearch:totalResults>95</opensearch:totalResults>
     <opensearch:startIndex>0</opensearch:startIndex>
     <opensearch:itemsPerPage>100</opensearch:itemsPerPage>

     <artist href="spotify:artist:2evydP72Z45DouM4uMGsIE">     
          <name>Ash</name>
          <popularity>0.72515</popularity>
     </artist>

     <artist href="spotify:artist:77zwstbi3x1IxnbDFg6uns">
          <name>Wishbone Ash</name>
          <popularity>0.67812</popularity>
     </artist>
</artists>

Ok, in the above let's say I wan't to get all artists from the XML using xmlSearch.

The usual way would be to specify the following:

<cfset xml = xmlParse(xmlString)>

<cfset artists = xmlSearch(xml,"/artists/artist")>

This *should* work fine - top level 'artist' node, followed by some 'opensearch' and 'artist' nodes. We should now have an array of artist nodes in our artists variable. But we don't. Why?

Well the simple answer is, look closely at the artist node. Notice the xmlns attributes? They define an XML namespace and throw the whole thing out of whack. Ok, it's part of the spec but to get around this with XMLSearch we need to change our call to the following:

<cfset artists = XMLSearch(xml,"/:artists/:artist")>

Simple change but this tells the command to ignore the namespace and just return all 'artist' nodes that sit underneath the 'artists' node.

A simple distinction but one that can save hours of hair tearing. :)

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
Dominic Watson's Gravatar One thing to be aware of is that when you have multiple nested default namespaces (it happens), even that solution doesn't work when searching particular elements. For that, namespaces need explicit mapping:

http://fusion.dominicwatson.co.uk/2008/03/xmlsearc...
# Posted By Dominic Watson | 11/12/10 2:17 PM
James Allen's Gravatar Hi Dominic,

Ah excellent tip - thank you.

Another gotcha to look out for when using XMLSearch.

Your BetterXml CFC sounds excellent. I'll be grabbing that to add to the toolbox me thinks.
# Posted By James Allen | 11/12/10 2:22 PM
CJM's Gravatar Thank you for this... it saved me a lot of hassle!
# Posted By CJM | 8/20/12 11:40 PM
Chris Allen's Gravatar Thank you! Very helpful.
# Posted By Chris Allen | 10/21/12 5:51 PM
Roberto Fonseca's Gravatar Great. Never used but really good to know!
# Posted By Roberto Fonseca | 11/23/12 6:10 PM
pud's Gravatar Thank you! Exactly what I needed.
# Posted By pud | 5/2/13 12:46 PM
Rocky Rosen's Gravatar Thank you so much for this tip. I'd been stuck on this error for months, and finding your advice finally fixed it.
# Posted By Rocky Rosen | 6/6/13 3:13 AM
James Allen's Gravatar Awesome! Glad it helped.
# Posted By James Allen | 6/8/13 3:46 PM
© 2014 James Allen | Contact Me
This blog runs on the awesome power of BlogCFC - created by Raymond Camden. This blog is running version 5.9.