HOWTO: Write Namespace-Agnostic XPath and XSLT

XPath (and by extension XSLT) are affected by the namespaces present in the document you are traversing/transforming as described nicely by Dare here. It is possible to write XPath expressions that effectively ignore namespaces however by using the local-name() XPath function so in a sample document like this

<foo xmlns=‘urn:foo’><?xml:namespace prefix = o ns = “urn:schemas-microsoft-com:office:office” />/o:p

<bar>/o:p

<asdf/>/o:p

</bar>            /o:p

</foo>/o:p

 /o:p

This expression will match the “bar” element  //[local-name()=‘bar’]

This one won’t //bar

 

Of course namespaces exist for a reason, so just blithely ignoring them is not necessarily the greatest idea except in the most ad-hoc circumstances. If you don’t want to use namespace prefixes in your expressions, or if the namespace you want to match elements from is the default namespace which doesn’t have a prefix you can use the namespace-uri() XPath function in conjunction with local-name() to match nodes like this

 

This will match the “bar” element in the urn:foo namespace //[local-name()=‘bar’ and namespace-uri() = ‘urn:foo’]

This is obviously much more long-winded than writing //f:bar if you’ve aliased f to urn:foo, but it can sometimes come in handy.