【问题标题】:How to write XPath to get node attribute value from a "Name Space XML" in Java如何编写 XPath 以从 Java 中的“名称空间 XML”中获取节点属性值
【发布时间】:2020-02-21 07:19:05
【问题描述】:

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 xml xpath xpath-2.0 domxpath


    【解决方案1】:

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

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

    String xpathExpression = "/root/namespace::ns1"
    

    【讨论】:

      【解决方案2】:

      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'])
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多