You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xmlbeans-user@xml.apache.org by Grant Kushida <Gr...@Overture.com> on 2004/07/20 01:40:42 UTC

XPath + Namespaces

I'm having trouble using XMLBeans and XPath to select nodes from a document which uses namespaces. I'm using the 1.0.3 binary tarball build.

I have a simple schema, which looks something like:
  <a:workbench xmlns:a="http://blah.com/a">
    <a:value name="foo"/>
    <a:value name="bar"/>
  </a:workbench>

I'd like to write xpaths such as:
  //a:value 		- get all values
  //a:value[@exact='foo'] 	- get all values named 'foo'

However, using the documented syntax:
  declare namespace a='http://blah.com/a' //a:value[@exact='foo']

does not return any results. Omitting the 'declare namespace' section does not return anything either.

After some investigation into the xmlbeans code (org.apache.xmlbeans.impl.store.Path), it seems that xpaths with namespaces and/or predicates get handled via Jaxen's XPath engine, instead of the internal xmlbeans engine.

Using Jaxen directly, you'd have to call org.jaxen.BaseXPath.addNamespace() to define namespaces programmatically - there does not seem to be a way to do this within the xpath String expression itself. But, the PathImpl/XBeansDelegate classes don't allow for any additional parameters, and also don't specify a generic way to define namespaces with each Xpath engine implementation.

So, I worked (alright, hacked) around the problem by calling addNamespace() on org.apache.xmlbeans.impl.xpath.jaxen.XBeansXPathAdv, which subclasses org.jaxen.BaseXPath. However, since I had no way to pass namespaces in, and was too lazy to parse strings, I just added my own namespace which is fine for my purposes.

How is this supposed to work? Seems to me that you should be able to pass in a prefix-uri Map in XMLOptions, perhaps using setLoadAdditionalNamespaces(), or parse the 'declare namespace' from the xpath string. Either way, the PathImpl/XBeansDelegate infrastructure would have to handle that specifically for each XPath implementation. 

Or is there another way to do this?