You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Next »

DFDL includes an expression language based on XPath.

Turns out that there are some "issues" with XPath 1.0 and XML namespaces.

Things that don't work

If you have XML data that has a namespace, such as:

<data xmlns="urn:someNamespaceOrOther"><a>75</a></data>

Well, it turns out that there is no standard way to get this XPath to work:

    /data/a 

There is no XPath 1.0-standard mechanism for associating a namespace with a prefix (or with the default namespace).  Such mechanisms are specific to the XPath-1.0 processor.

Things that work

There are a few ways to deal with this problem.

0) Bind the namespaces using the XPath-1.0 processor

XPath-1.0 processors typically provide a way to bind namespace external to the XPath 1.0 expression.  For example, in JAXB, namespaces are bound to prefixes (and to the default namespace) using the NamespaceContext method. 

See XPath.html and the discussion on QNames in the class overview. Also see NamespaceContext.html for details on how to bind the default namespace.

1) Avoid Namespaces

If you have all non-qualfied elements with none of these xmlns="..." things around like this:

<data><a>75</a></data>

well, this works fine with the XPath /data/a.

2) Prefix All Element Names:

You can qualify every element. This is in some sense the most robust approach. So if you write:

<tns:data xmlns:tns="urn:someNamespaceOrOther"><tns:a>75</tns:a></tns:data>

Then the path

/tns:data/tns:a 

is meaningful and works.  However, for an XPath-1.0 processor, the tns prefix will need to be bound before the XPath expression will evaluate successfully.  See option (0) above for details.  (Note that this path will work without any hassle in an XPath-2.0 processor.)

3) Use Both Non-Qualfied Names and a Prefix

If you really can't stand the tns prefix clutter in the data, then you can add a prefix along side the non-prefix namespace. This prefix is there for XPath:

<data xmlns="urn:someNamespaceOrOther" xmlns:tns="urn:someNamespaceOrOther"><a>75</a></data>

This tns prefix definition enables qualified XPath expressions to also work. Notice that the unqualified namespace and the tns namespace prefix are bound to the same namespace, so this path:

/tns:data/tns:a

also works in this case.  Again, see note above on binding namespaces.

4) Match the namespace and/or the local-name of the element in the XPath expression

For the original example, this XPath 1.0 expression should work:

/*[local-name() = 'data' and namespace() = 'urn:someNamespaceOrOther']/*[local-name() = 'a' and namespace() = 'urn:someNamespaceOrOther']

Summary

There are several ways to get namespaces to work with XPath 1.0, but none of them are pretty or elegant.

  • No labels