Java XPath: queries with default xmlns namespace

I want to make an XPath request in this file (excerpt outlined):

<?xml version="1.0" encoding="UTF-8"?> <!-- MetaDataAPI generated on: Friday, May 25, 2007 3:26:31 PM CEST --> <ModelClass xmlns="http://xml.sap.com/2002/10/metamodel/webdynpro" xmlns:IDX="urn:sap.com:WebDynpro.ModelClass:2.0"> <ModelClass.Parent> <Core.Reference package="com.test.mypackage" name="ModelName" type="Model"/> 

This is the code snippet I'm using:

 DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = domFactory.newDocumentBuilder(); Document document = builder.parse(new File(testFile)); XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); xpath.setNamespaceContext( new NamespaceContext() { public String getNamespaceURI(String prefix) { ... String result = xpath.evaluate(xpathQueryString, document); System.out.println(result); 

The problem I'm encountering is that when the default namespace is referenced in an XPath request, the getNamespaceURI method is not called to fix it. This query, for example, does not retrieve anything:

//xmlns:ModelClass.Parent/xmlns:Core.Reference[@type=\"Model\"]/@package

Now I tried to β€œtrick” the parser by replacing xmlns false prefix d and then typing the getNamespaceURI method getNamespaceURI (to return http://xml.sap.com/2002/10/metamodel/webdynpro when d is encountered). In this case, getNamespaceURI is getNamespaceURI , but the result of evaluating an XPath expression is always an empty string.

If I struck out the namespaces from the file and from the XPath query expression, I can get the desired line (com.test.mypackage).

Is there a way to work with the default namespace correctly?

+7
java xml namespaces xpath xml-namespaces
May 23 '12 at 12:59 a.m.
source share
2 answers

In the Namespace context, attach the prefix of your choice (e.g. df ) to the namespace URI in the document

 xpath.setNamespaceContext( new NamespaceContext() { public String getNamespaceURI(String prefix) { switch (prefix) { case "df": return "http://xml.sap.com/2002/10/metamodel/webdynpro"; ... } }); 

and then use this prefix in the path expressions to specify element names, for example. /df:ModelClass/df:ModelClass.Parent/df:Core.Reference[@type = 'Model']/@package .

+8
May 23 '12 at 1:26
source share

The XPath 1.0 specification requires "no prefix to denote a namespace." Therefore, JAXP, which was developed for XPath 1.0, is absolutely right to stop binding the "null prefix" to some non-empty namespace.

XPath 2.0 allows you to declare a default namespace for unqualified names in an XPath expression, but to take advantage of this, you need an API (such as Saxon s9api) that uses this function.

+10
May 23 '12 at 16:19
source share



All Articles