有“原始”XML
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header>
<context xmlns="urn:zimbra">
<session id="555">555</session>
<change token="333"/>
</context>
</soap:Header>
<soap:Body>
<AuthResponse xmlns="urn:zimbraAccount">
<lifetime>172799999</lifetime>
<session id="555">555</session>
<skin>carbon</skin>
</AuthResponse>
</soap:Body>
</soap:Envelope>XML是以这种方式解析的。
// javax.xml.parsers.*
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(pathToXml);然后我尝试提取XPath的会话id
// javax.xml.xpath.*;
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
// next xpath does not work with Java and online xpath tester
//XPathExpression expr = xpath.compile("/soap:Envelope/soap:Header/context/session/text()");
// this xpath works with online xpath tester but does not with in Java
XPathExpression expr = xpath.compile("/soap:Envelope/soap:Header/*[name()='context']/*[name()='session']/text()");
String sessionId = (String)expr.evaluate(doc, XPathConstants.STRING);在这里测试http://www.xpathtester.com/xpath/678ae9388e3ae2fc8406eb8cf14f3119
当XML简化为以下内容时
<Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<Header>
<context>
<session id="555">555</session>
<change token="333"/>
</context>
</Header>
<Body>
<AuthResponse xmlns="urn:zimbraAccount">
<lifetime>172799999</lifetime>
<session id="555">555</session>
<skin>carbon</skin>
</AuthResponse>
</Body>
</Envelope>这个XPath完成了它的工作
XPathExpression expr = xpath.compile("/Envelope/Header/context/session/text()");如何用Java从“原始”XML中提取会话id?
更新: JDK 1.6
发布于 2014-04-21 18:43:11
答案是你需要correctly use namespaces and namespace prefixes
首先,在使用DocumentBuilderFactory名称空间之前调用它,从而使其意识到:
factory.setNamespaceAware(true); 然后执行此操作以检索所需的值:
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
xpath.setNamespaceContext(new NamespaceContext() {
@Override
public String getNamespaceURI(String prefix) {
if (prefix.equals("soap")) {
return "http://www.w3.org/2003/05/soap-envelope";
}
if (prefix.equals("zmb")) {
return "urn:zimbra";
}
return XMLConstants.NULL_NS_URI;
}
@Override
public String getPrefix(String namespaceURI) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Iterator getPrefixes(String namespaceURI) {
throw new UnsupportedOperationException("Not supported yet.");
}
});
XPathExpression expr =
xpath.compile("/soap:Envelope/soap:Header/zmb:context/zmb:session");
String sessionId = (String)expr.evaluate(doc, XPathConstants.STRING);您可能需要在文件的开头添加一行以导入NamespaceContext类:
import javax.xml.namespace.NamespaceContext;http://ideone.com/X3iX5N
发布于 2014-04-22 05:38:51
您可以始终通过忽略命名空间来完成这一任务,这不是理想的方法,而是有效的。
"/*[local-name()='Envelope']/*[local-name()='Header']/*[local-name()='context']/*[local-name()='session']/text()"https://stackoverflow.com/questions/23203421
复制相似问题