Why doesnt my XPath work with unprefixed path elements?

Ramkumar Menon
Director, Product Strategy

Assume that you had an XML Document like the one illustrated below.


  2. <purchaseOrder xmlns="www.oracle.com/po">  

  3.   <id>100</id>  

  4.   <items>  

  5.    <item name="TV">  

  6.      <description>television</description>  

  7.    </item>  

  8.    <item name=VCR">  

  9.      <description>Video Cassette Recorder</description>  

  10.    </item>  

  11.    <item name="DVD">  

  12.      <description>Digital Video Disc</description>  

  13.    </item>  

  14.   </items>  

  15.   <comment>PO from Ramkumar Menon</comment>  

  16. </purchaseOrder>  
You had a piece of java code in which you wish to get the comments from the purchaseOrder. You choose to use the "selectNodes()" API to get the value.



  3. DOMParser parser = new DOMParser();   

  4. StringReader reader = new StringReader(poXMLString);   

  5. parser.parse(reader);;   

  6. XMLDocument doc = parser.getDocument();   

  7. XMLElement docElement = (XMLElement)doc.getDocumentElement();   

  8. NodeList list = doc.selectNodes("/purchaseOrder/comment",docElement);   

  9. System.err.println("number of items in the list = " + list.getLength());  
Result - Guess what! It is zero. Why ? Here you go! The Location path expression that I just modeled contains a set of location steps "purchaseOrder"and "comment". Xpath expects each of the node names within the location steps to be a QName. [consisting of a namespace URI and a local name]

But, yes, but, if the namespace prefix on the node name is specified to be "empty", the nodes are assumed to come from null namespace, and not the default namespace.

That is exactly why you get zero nodes on the evaluation of the expression.

Whats the workaround?

  1. Ensure that the path elements have a namespace prefix, or

  2. You could use wildcard expressions . For instance,the above expression could be re-written as "/*[local-name()='purchaseOrder'][namespace-uri()='www.oracle.com/po'] /*[local-name()='comments'[namespace-uri()='www.oracle.com/po'] You could use either of these approaches, and you've got what you wished for!

Join the discussion

Comments ( 2 )
  • Phil Fearon Saturday, September 22, 2007
    An alternative is to associate an explicit chosen prefix with the default namespace URI using an implementation of the javax.xml.namespace.NamespaceContext interface.
    This technique is described in an excellent article by Elliote Rusty Harold at: http://www.ibm.com/developerworks/library/x-javaxpathapi.html
  • Ramkumar Menon Monday, September 24, 2007

    Another option would be to implement the interface oracle.xml.parser.v2.NSResolver and have it return the default namespace URI if the prefix is empty.


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.