简体   繁体   中英

JAVA & XML : com.sun.org.apache.xpath.internal.XPathException: Can not convert #STRING to a NodeList

I am writing a java function that is parsing an xml element & extracting the given xpath expression. Below is the function :

public static Node getDataNode(Element payload, final HashMap<String, String> namespaces, String xpathStr) {
    Node node = null;
    try {
        // Create a namespace context based on the namespaces passed in.
        NamespaceContext ctx = new NamespaceContext() {
            public String getNamespaceURI(String prefix) {
                return namespaces.get(prefix);
            }

            public Iterator getPrefixes(String val) {
                return null;
            }

            public String getPrefix(String uri) {
                return null;
            }
        };
        XPathFactory xpathFact = XPathFactory.newInstance();
        XPath xpath = xpathFact.newXPath();
        xpath.setNamespaceContext(ctx);
        XPathExpression expr = xpath.compile(xpathStr);
        System.out.println("Got request to process node : " + payload.getLocalName() + " with " + xpathStr);
        System.out.println(xpathStr + " has been compiled successfully.");
        ((XMLElement) payload).print(System.out);
        node = (Node) expr.evaluate(payload, XPathConstants.NODE);
    } catch (XPathExpressionException ex) {
        ex.printStackTrace();
        return null;
        } catch (IOException io) {
            io.printStackTrace();
            return null;
        }
    return node;
}

Below is the logs for this part of function :

Got request to process node : Body with ".//soapenv:Body/pip:request"
".//soapenv:Body/pip:request" has been compiled successfully.
<soapenv:Body xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
      <pip:request xmlns:pip="http://xmlns.oracle.com/ServiceBusApplication/UserInterfaceTest/Pipeline">textContent</pip:request>
   </soapenv:Body>

I have tried different xpath expression like //soapenv:Body/pip:request, .//soapenv:Body/pip:request but still i am getting the error :

 com.sun.org.apache.xpath.internal.XPathException: Can not convert #STRING to a NodeList! at com.sun.org.apache.xpath.internal.objects.XObject.error(XObject.java:711) at com.sun.org.apache.xpath.internal.objects.XObject.nodeset(XObject.java:441) at com.sun.org.apache.xpath.internal.jaxp.XPathExpressionImpl.getResultAsType(XPathExpressionImpl.java:357) at com.sun.org.apache.xpath.internal.jaxp.XPathExpressionImpl.eval(XPathExpressionImpl.java:101) at com.sun.org.apache.xpath.internal.jaxp.XPathExpressionImpl.evaluate(XPathExpressionImpl.java:182) 

Please let me know what is wrong in the code.Appreciate your help in resolving the issue . Thanks.

Unable to reproduce. Tested with MCVE code below on Oracle JDK 1.5 and on Oracle JDK 9.

Only change made to getDataNode method is commenting out the ((XMLElement) payload).print(System.out) statement, since Oracle JDK doesn't have an XMLElement type.

Test

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

import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
String xml = "<soapenv:Body xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
             "      <pip:request xmlns:pip=\"http://xmlns.oracle.com/ServiceBusApplication/UserInterfaceTest/Pipeline\">textContent</pip:request>\n" +
             "   </soapenv:Body>";
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder domBuilder = domFactory.newDocumentBuilder();
Document document = domBuilder.parse(new InputSource(new StringReader(xml)));

HashMap<String, String> namespaces = new HashMap<String, String>();
namespaces.put("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
namespaces.put("pip", "http://xmlns.oracle.com/ServiceBusApplication/UserInterfaceTest/Pipeline");

Node node = getDataNode(document.getDocumentElement(), namespaces, ".//soapenv:Body/pip:request");
System.out.println(node != null ? node.getTextContent() : null);

node = getDataNode(document.getDocumentElement(), namespaces, "/soapenv:Body/pip:request");
System.out.println(node != null ? node.getTextContent() : null);

node = getDataNode(document.getDocumentElement(), namespaces, ".//pip:request");
System.out.println(node != null ? node.getTextContent() : null);

Output

Got request to process node : Body with .//soapenv:Body/pip:request
.//soapenv:Body/pip:request has been compiled successfully.
null
Got request to process node : Body with /soapenv:Body/pip:request
/soapenv:Body/pip:request has been compiled successfully.
textContent
Got request to process node : Body with .//pip:request
.//pip:request has been compiled successfully.
textContent

As you can see, code runs fine, but the .//soapenv:Body/pip:request XPath is not correct for the given XML, since there is no <soapenv:Body> tag inside the given payload element.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM