我正在编写一个Java函数,该函数解析xml元素并提取给定的xpath表达式。下面是函数:
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;
}
以下是该功能部分的日志:
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>
我尝试了不同的xpath表达式,例如//soapenv:Body/pip:request、.//soapenv:Body/pip:request,但仍然出现错误:
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)
请让我知道代码中有什么问题。感谢您为解决问题提供的帮助。谢谢。
答案 0 :(得分:0)
无法复制。在Oracle JDK 1.5和Oracle JDK 9上使用下面的MCVE代码进行了测试。
由于Oracle JDK没有getDataNode
类型,因此仅对((XMLElement) payload).print(System.out)
方法所做的更改会注释掉XMLElement
语句。
测试
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);
输出
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
如您所见,代码运行良好,但是.//soapenv:Body/pip:request
XPath对于给定的XML不正确,因为在给定的{{里面没有<soapenv:Body>
标记 1}}元素。