Search code examples
javanamespacesdom4j

DOM4J xpath-select colon node with namespace


Given the xml content is as below;

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><CreateResponse xmlns="http://gtestserver/"><CustomerId>8124138</CustomerId><InternalResponseCode>Success</InternalResponseCode><ResponseCode>0</ResponseCode><ResponseDate>2016-08-31T07:57:22.7760577Z</ResponseDate><ResponseDescription>Success</ResponseDescription><UserId>7424876375</UserId></CreateResponse></s:Body></s:Envelope>

I need to pickup the node :CustomerId ,but i cannot get it correctly ,the code i used here:

 Document document = new SAXReader().read(new ByteArrayInputStream(xmlfile.getBytes("UTF-8")));
 Node foundnode = null;
 Element rootElement = document.getRootElement();
 String namespace = rootElement.getNamespaceURI();
 if (namespace != null) {
     DefaultXPath defaultXPath = new DefaultXPath(xpath);
     Map<String, String> namespaces = new TreeMap<String, String>();
     namespaces.put("ns", namespace);
     defaultXPath.setNamespaceURIs(namespaces);
 }
 foundnode = document.selectSingleNode("/ns:s:Envelope/ns:s:Body/ns:CreateResponse/ns:CustomerId");

Then it throws below exception :

org.dom4j.InvalidXPathException: Invalid XPath expression: /ns:s:Envelope/ns:s:Body/ns:CreateResponse/ns:CustomerId Unexpected ':'
    at org.dom4j.xpath.DefaultXPath.parse(DefaultXPath.java:360)
    at org.dom4j.xpath.DefaultXPath.<init>(DefaultXPath.java:59)
    at com.github.becauseQA.xml.DOM4JUtils.getNodes(DOM4JUtils.java:152)
    at 

I know it caused by the xpath used here ,but i don't know which xpath should i pickup here, you can see the node has : ,so when use the namespace with ns: for each node ,it cannot parse it . Anyone know how to pickup the node with namespace and special character in the node name ? thanks .


Solution

  • You can try the following :

    String xml = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><CreateResponse xmlns=\"http://gtestserver/\"><CustomerId>8124138</CustomerId><InternalResponseCode>Success</InternalResponseCode><ResponseCode>0</ResponseCode><ResponseDate>2016-08-31T07:57:22.7760577Z</ResponseDate><ResponseDescription>Success</ResponseDescription><UserId>7424876375</UserId></CreateResponse></s:Body></s:Envelope>";
    
    Document document = new SAXReader().read(new ByteArrayInputStream(xml.getBytes("UTF-8")));
    Node foundnode = null;
    Element rootElement = document.getRootElement();
    String namespace = rootElement.getNamespaceURI();
    
    foundnode = document.selectSingleNode("//*[local-name()='CustomerId']");
    
    System.out.println(foundnode.getText());
    

    This returns : 8124138