« Generating XML files from XML Schema | Main | Intelligent proxies »
April 21, 2006
XPath and default namespaces
Using default namespaces in XPath expressions seems to be a little bit complicated. The following code excerpt shows the problem:
public static void main(String[] args) throws Exception
{
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
XPath xPath = XPathFactory.newInstance().newXPath();
Document doc = documentBuilder.parse(new File("C:/test.xml"));
Node node =(Node) xPath.evaluate("/address", doc, XPathConstants.NODE);
System.out.println(node);
}
The corresponding XML file looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<address xmlns="http://wsiftypes.addressbook/" />
On the first view the XPath expression "/address" should match the root element "address" of the XML document. But this does not work. The resulting node is "null".
The element "address" is assigned to the namespace "http://wsiftypes.addressbook/" and must be used in the XPath expression. Because it is not possible to map this namespace to an empty prefix it must be mapped to a named prefix.
The above code is changed to use an Implementation of the interface NamespaceContext that maps namespaces to prefixes and the other way round. So using the default namespace works like this:
public static void main(String[] args) throws Exception
{
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
XPath xPath = XPathFactory.newInstance().newXPath();
Document doc = documentBuilder.parse(new File("C:/test.xml"));
NamespaceContextImpl nci = new NamespaceContextImpl();
nci.setNamespaceURI("typens","http://wsiftypes.addressbook/");
xPath.setNamespaceContext(nci);
Node node =(Node) xPath.evaluate("/typens:address", doc, XPathConstants.NODE);
System.out.println(node);
}
Posted by Dominik Marks at April 21, 2006 10:35 AM