如何用Java中的XPath区分这两个XML?
<iq type="result">
<query xmlns="jabber:iq:roster">
</query>
</iq>
和
<iq type="result">
<query xmlns="vcard-temp">
</query>
</iq>
我试过这个,它总是打印出来,
public class Test {
public static void main(String[] args) throws Exception {
final String xml = "<iq type=\"result\"><query xmlns=\"jabber:iq:roster\"></query></iq>";
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document document = builder.parse(createInputSource(xml));
XPath xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(new NamespaceContext() {
@Override
public String getNamespaceURI(String prefix) {
switch (prefix) {
case "roster":
return "jabber:iq:roster";
case "vcard":
return "vcard-temp";
}
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.");
}
});
Node match = (Node) xpath.evaluate("/iq/roster:query", document, XPathConstants.NODE);
System.out.println(match);
}
private static InputSource createInputSource(String xml) {
return new InputSource(new StringReader(xml));
}
}
答案 0 :(得分:2)
您使用XPath查询XML文档时使用的API很可能有一种方法可以为命名空间注册名称空间前缀,例如使用NamespaceContext。 因此,您将为每个命名空间分配不同的前缀,并使用以下内容检索相应的节点:
/iq/jRoster:query
/iq/vcard:query
另一个选项是跳过NamespaceContext并使用namespace-uri():
/iq/*[local-name() = "query" and namespace-uri() = "jabber:iq:roster"]
/iq/*[local-name() = "query" and namespace-uri() = "vcard-temp"]
在创建文档构建器时,您似乎还需要使用setNamespaceAware(true):
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();