如何编写XPath以从Java中的“名称空间XML”获取节点属性值

问题描述 投票:0回答:2

INPUT_XML:

<?xml version="1.0" encoding="UTF-8">
<root xmlns:ns1="http://path1/schema1" xmlns:ns2="http://path2/schema2">
    <ns1:abc>1234</ns1:abc>
    <ns2:def>5678</ns2:def>
</root>

在Java中,我试图编写XPath表达式,该表达式将从上面的INPUT_XML字符串内容中获取与此属性“ xmlns:ns1”相对应的值。

我尝试了以下操作:

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setNamespaceAware(true);
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document document = builder.parse(INPUT_XML);

    String xpathExpression = "/root/xmlns:ns1";

    // Create XPathFactory object
    XPathFactory xpathFactory = XPathFactory.newInstance();

    // Create XPath object
    XPath xpath = xpathFactory.newXPath();

    // Create XPathExpression object
    XPathExpression expr = xpath.compile(xpathExpression);

    // Evaluate expression result on XML document
    NodeList nodes = (NodeList) expr.evaluate(document, XPathConstants.NODESET);

    for (int i = 0; i < nodes.getLength(); i++) {
        System.out.println(nodes.item(i).getNodeValue());
    }

但是上面的代码没有给出指定属性的期望值,即xmlns:ns1。我严重怀疑xPathExpression是错误的。请提出正确的XPath表达式或解决此问题的正确方法。

java xpath xpath-2.0 nsindexpath domxpath
2个回答
0
投票

xmlns:ns1="http://path1/schema1"xmlns:ns2="http://path2/schema2"不是属性,而是namespace declarations。您不能轻易地使用XPath声明来检索它们(为此目的,它具有XPath函数namespace-uri(),但根元素没有任何命名空间,它仅定义它们以供将来使用)。

使用DOM API时,可以使用lookupNamespaceURI()方法:

System.out.println("ns1 = " + doc.getDocumentElement().lookupNamespaceURI("ns1"));
System.out.println("ns2 = " + doc.getDocumentElement().lookupNamespaceURI("ns2"));

使用XPath时,您可以尝试以下表达式:

namespace-uri(/*[local-name()='root']/*[local-name()='abc'])
namespace-uri(/*[local-name()='root']/*[local-name()='def'])

0
投票

如果使用的是XPath 1.0处理器,或者启用了XPath 1.0兼容模式的XPath 2.0处理器,则可以使用namespace轴来选择名称空间值。

您将需要在代码中进行以下更改:

String xpathExpression = "/root/namespace::ns1"
© www.soinside.com 2019 - 2024. All rights reserved.