TheCodeCache
TheCodeCache

Reputation: 972

How to write XPath to get node attribute value from a "Name Space XML" in Java

INPUT_XML:

<?xml version="1.0" encoding="UTF-8">
<root xmlns:ns1="http://path1/schema1" xmlns:ns2="http://path2/schema2">
    <ns1:abc>1234</ns1:abc>
    <ns2:def>5678</ns2:def>
</root>

In Java, I am trying to write XPath expression which will get the value corresponding to this attribute "xmlns:ns1" from the above INPUT_XML string content.

I've tried the following:

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setNamespaceAware(true);
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document document = builder.parse(INPUT_XML);

    String xpathExpression = "/root/xmlns:ns1";

    // Create XPathFactory object
    XPathFactory xpathFactory = XPathFactory.newInstance();

    // Create XPath object
    XPath xpath = xpathFactory.newXPath();

    // Create XPathExpression object
    XPathExpression expr = xpath.compile(xpathExpression);

    // Evaluate expression result on XML document
    NodeList nodes = (NodeList) expr.evaluate(document, XPathConstants.NODESET);

    for (int i = 0; i < nodes.getLength(); i++) {
        System.out.println(nodes.item(i).getNodeValue());
    }

But the above code is not giving the expected value of the specified attribute i.e. xmlns:ns1. I heavily suspect the xPathExpression is wrong. Please suggest with the right XPath expression or the right approach to tackle this issue.

Upvotes: 1

Views: 901

Answers (2)

Robby Cornelissen
Robby Cornelissen

Reputation: 97331

If you're using an XPath 1.0 processor, or a XPath 2.0 processor with XPath 1.0 compatibility mode turned on, you can use the namespace axis to select the namespace value.

You will need to make the following change in your code:

String xpathExpression = "/root/namespace::ns1"

Upvotes: 1

Daniil
Daniil

Reputation: 953

The xmlns:ns1="http://path1/schema1" and xmlns:ns2="http://path2/schema2" are not attributes, but namespace declarations. You cannot retrieve them with an XPath declaration so easily (there is XPath function namespace-uri() for this purpose, but root element does not have any namespace, it only defines them for future use).

When using DOM API you could use method lookupNamespaceURI():

System.out.println("ns1 = " + doc.getDocumentElement().lookupNamespaceURI("ns1"));
System.out.println("ns2 = " + doc.getDocumentElement().lookupNamespaceURI("ns2"));

When using XPath you could try following expressions:

namespace-uri(/*[local-name()='root']/*[local-name()='abc'])
namespace-uri(/*[local-name()='root']/*[local-name()='def'])

Upvotes: 0

Related Questions