Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to retrieve XML data using XPath which contains namespace in Java?

Tags:

java

xml

xpath

i know there are plenty of this topic in this page but sadly, i still cant get my solution..

here is my xml code:

<?xml version="1.0" encoding="UTF-8"?>
<ns1:Request xmlns:ns1="http://www.sea.com">
<ns1:PayrollRequest>
  <ns1:PayrollCost>
    <ns1:PayrollID>123</ns1:PayrollID>
    <ns1:BatchID>7770</ns1:BatchID>
    <ns1:CompanyId>001</ns1:CompanyId>
    <ns1:GrossPay>60000</ns1:GrossPay>
  </ns1:PayrollCost>
</ns1:PayrollRequest>
</ns1:Request>

and this is my code in java:

import org.w3c.dom.*;
import javax.xml.xpath.*;
import javax.xml.parsers.*;
import java.io.IOException;
import org.xml.sax.SAXException;

public class XPathTry {

public static void main(String[] args) 
throws ParserConfigurationException, SAXException, 
IOException, XPathExpressionException {

DocumentBuilderFactory domFactory = 
DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true); 
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse("SamplePayroll2.xml");
XPath xpath = XPathFactory.newInstance().newXPath();


// display all
XPathExpression expr = xpath.compile("//PayrollCost/*/text()");


Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++) {
System.out.println(nodes.item(i).getNodeValue()); 
   }
  }
}

ya, as usual, i cant get the output as it only displays:

Process exited with exit code 0.

the output will only display when i remove the ns:1 which the code for the xml will be like this:

<?xml version="1.0" encoding="UTF-8"?>
<Request xmlns:ns1="http://www.sea.com">
<PayrollRequest>
    <PayrollCost>
        <PayrollID>123</PayrollID>
        <BatchID>7770</BatchID>
        <CompanyId>001</CompanyId>
        <GrossPay>60000</GrossPay>
    </PayrollCost>
</PayrollRequest>
</Request>

The problem is, all the suggestions i found in the net none seems to be working:

for example, i already tried the

/*/namespace::*[name()='']

//*[local-name() = 'Element' and namespace-uri() = namespace-uri(/*)]

/*[local-name()=' ']/*[local-name()=' ']/*[local-name()=' ']

etc2..

the only best output i can get is, it will display:

null

can anyone give me the correct code for my problem?

Thanks in Advance!

like image 373
user1050754 Avatar asked Nov 22 '11 03:11

user1050754


People also ask

How does XPath handle namespace?

XPath queries are aware of namespaces in an XML document and can use namespace prefixes to qualify element and attribute names. Qualifying element and attribute names with a namespace prefix limits the nodes returned by an XPath query to only those nodes that belong to a specific namespace.

How do I find the XPath namespace?

There is no method to connect a namespace prefix to a namespace in XPath. The hosting library can provide these services. It is strongly advised that we take advantage of those features and create namespace prefixes that may be used to qualify XML element and attribute names as needed.

How do I find the XML namespace?

XML Namespaces - The xmlns Attribute When using prefixes in XML, a namespace for the prefix must be defined. The namespace can be defined by an xmlns attribute in the start tag of an element. The namespace declaration has the following syntax. xmlns:prefix="URI".


1 Answers

You are going to have to create a subclass of javax.xml.namespace.NamespaceContext and set it on xpath:

xpath.setNamespaceContext(new NamespaceContext() {

    @SuppressWarnings("rawtypes")
    @Override
    public Iterator getPrefixes(final String namespaceURI) {
        return Collections.singleton("ns1").iterator();
    }

    @Override
    public String getPrefix(final String namespaceURI) {
        return "ns1";
    }

    @Override
    public String getNamespaceURI(final String prefix) {
        return "http://www.sea.com";
    }
});

Then you can add the namespace prefix to the XPath expression:

XPathExpression expr = xpath.compile("//ns1:PayrollCost/*/text()");
like image 194
laz Avatar answered Sep 22 '22 08:09

laz