Selecting node based on namespace in xPath

I'm used to XPath, I use it in my Javascript dev (jQuery) has well as in my cakePHP dev (the Set::extract() method), and I've always thought it was really fast, powerful and readable.

Today I had to parse a real-world XML file, and I discovered that when dealing with namespaces, all became suddenly much more difficult in the XPath world.

Here is my xml source (shortened for the sake of clarity) :

<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
 <x:xmpmeta xmlns:x="adobe:ns:meta/">
 <rdf:RDF xmlns:rdf="">

 <rdf:Description rdf:about="" xmlns:dc="">
 <dc:creator>Igor Gosstroff</dc:creator>
 <dc:description xml:lang="x-default">Awesome picture</dc:description>

 <rdf:Description rdf:about="" xmlns:xmp="">

<?xpacket end="w"?>

I wanted to select the first <rdf:Description> (Dublin Core).

First of all, you have to know that you can't do //rdf:description, you have to use a special syntax because the : is a reserved character. The solution is using the name() method : //*[name()='rdf:Description'].

It will return both rdf:Description nodes. I can easily get the one i'm interested in by doing //*[name()='rdf:Description'][1] but I would have liked to use a much more simple syntax and select the one with an xmlns:dc attribute.

And I did not find out how to do that. All the syntaxes I tried either returned nothing, threw and exception and even crash my app once.

I finally found a devious way to find it. I search for any xmlField whose namespace uri was and then get its parent. I still feel like its a dirty hack but I've allready spent too much time on it, so it will be enough for now.


Tags : #xpath #xmp #xml #namespace #coldfusion

Want to add something ? Feel free to get in touch on Twitter : @pixelastic