Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parse XML with namespaces in Java using xpath

Tags:

java

soap

xml

xpath

I am trying to parse SOAP request in java but code is not returning any nodes here is the code can anybody find error

        String xml="<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ser=\"http://services.web.post.list.com\"><soapenv:Header><authInfo xsi:type=\"soap:authentication\" xmlns:soap=\"http://list.com/services/SoapRequestProcessor\"><!--You may enter the following 2 items in any order--><username xsi:type=\"xsd:string\">[email protected]</username><password xsi:type=\"xsd:string\">PfasdfRem91</password></authInfo></soapenv:Header></soapenv:Envelope>"; 
    System.out.println(xml);
    DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
    domFactory.setNamespaceAware(true);
    DocumentBuilder builder = domFactory.newDocumentBuilder();
    Document doc = builder.parse(new InputSource(new StringReader(xml)));
    XPath xpath = XPathFactory.newInstance().newXPath();
    // XPath Query for showing all nodes value

    try
    {
    XPathExpression expr = xpath.compile("/soapenv:Envelope/soapenv:Header/authInfo/password");
    Object result = expr.evaluate(doc, XPathConstants.NODESET);
    NodeList nodes = (NodeList) result;
    System.out.println("Got " + nodes.getLength() + " nodes");
//    System.out.println(nodes.item(0).getNodeValue());
    }
    catch(Exception E)
    {
        System.out.println(E);
    }

like image 624
Raheel Avatar asked Jul 25 '12 07:07

Raheel


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.

What is namespace node in XPath?

Introduction to XPath namespace. In an XML document, namespaces are used to provide uniquely named components and attributes. A namespace is made up of two parts: a prefix and a URL. This indicates the location of a document that defines the namespace in question.

What is XPath parsing?

It defines a language to find information in an XML file. It is used to traverse elements and attributes of an XML document.


2 Answers

You need to set a NamespaceContext on the XPath:

Demo

package forum11644994;

import java.io.StringReader;
import java.util.Iterator;

import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.*;
import javax.xml.xpath.*;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

public class Demo {

    public static void main(String[] args) throws Exception {
        String xml = "<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ser=\"http://services.web.post.list.com\"><soapenv:Header><authInfo xsi:type=\"soap:authentication\" xmlns:soap=\"http://list.com/services/SoapRequestProcessor\"><!--You may enter the following 2 items in any order--><username xsi:type=\"xsd:string\">[email protected]</username><password xsi:type=\"xsd:string\">PfasdfRem91</password></authInfo></soapenv:Header></soapenv:Envelope>";
        System.out.println(xml);
        DocumentBuilderFactory domFactory = DocumentBuilderFactory
                .newInstance();
        domFactory.setNamespaceAware(true);
        DocumentBuilder builder = domFactory.newDocumentBuilder();
        Document doc = builder.parse(new InputSource(new StringReader(xml)));
        XPath xpath = XPathFactory.newInstance().newXPath();
        xpath.setNamespaceContext(new NamespaceContext() {

            @Override
            public Iterator getPrefixes(String arg0) {
                return null;
            }

            @Override
            public String getPrefix(String arg0) {
                return null;
            }

            @Override
            public String getNamespaceURI(String arg0) {
                if("soapenv".equals(arg0)) {
                    return "http://schemas.xmlsoap.org/soap/envelope/";
                }
                return null;
            }
        });
        // XPath Query for showing all nodes value

        try {
            XPathExpression expr = xpath
                    .compile("/soapenv:Envelope/soapenv:Header/authInfo/password");
            Object result = expr.evaluate(doc, XPathConstants.NODESET);
            NodeList nodes = (NodeList) result;
            System.out.println("Got " + nodes.getLength() + " nodes");
            // System.out.println(nodes.item(0).getNodeValue());
        } catch (Exception E) {
            System.out.println(E);
        }

    }
}

Output

<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.web.post.list.com"><soapenv:Header><authInfo xsi:type="soap:authentication" xmlns:soap="http://list.com/services/SoapRequestProcessor"><!--You may enter the following 2 items in any order--><username xsi:type="xsd:string">[email protected]</username><password xsi:type="xsd:string">PfasdfRem91</password></authInfo></soapenv:Header></soapenv:Envelope>
Got 1 nodes
like image 75
bdoughan Avatar answered Nov 07 '22 16:11

bdoughan


Adding some more to the latest reply.. To get the particular node value you can use the below-- [System.out.println(nodes.item(0).getTextContent());]

like image 42
Abhishek Avatar answered Nov 07 '22 14:11

Abhishek