【问题标题】:Java XPath Compile can't query tag with unique namespaceJava XPath Compile 无法查询具有唯一命名空间的标签
【发布时间】:2015-09-11 16:17:20
【问题描述】:

我有一个标签,里面有一个唯一的命名空间,只有那个标签。我引入了 XML 命名空间上下文,但我的程序仍然返回 0 个节点。

// Create DocumentBuilderFactory for reading xml file
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();

        factory.setNamespaceAware(true);

        Document doc = builder.parse(new InputSource(new StringReader(text)));

        // Create XPathFactory for creating XPath Object
        XPathFactory xPathFactory = XPathFactory.newInstance();

        // Create XPath object from XPathFactory
        XPath xpath = xPathFactory.newXPath();

        xpath.setNamespaceContext(new NamespaceContext() {
            public String getNamespaceURI(String prefix) {
                if ("cam".equals(prefix))
                    return "urn:xxx:1.0:logging";
                else if ("soapenv".equals(prefix))
                    return "http://schemas.xmlsoap.org/soap/envelope/";
                else if ("xml".equals(prefix))
                    return XMLConstants.XML_NS_URI;
                return XMLConstants.NULL_NS_URI;
            }

            // This method isn't necessary for XPath processing.
            public String getPrefix(String uri) {
                throw new UnsupportedOperationException();
            }

            // This method isn't necessary for XPath processing either.
            public Iterator getPrefixes(String uri) {
                throw new UnsupportedOperationException();
            }
        });

        // Compile the XPath expression for getting the response
         XPathExpression xPathExpr =
         xpath.compile("/cam:message/cam:response/soapenv:Envelope/soapenv:Header/Info[1]/property[@name='response']/text()");
        

        // XPath text example : executing xpath expression in java
        // Object result = xPathExpr.evaluate(doc, XPathConstants.NODESET);
        // NodeList nodes = (NodeList) result;
        // int length = nodes.getLength();

        String result1 = (String) xPathExpr.evaluate(doc, XPathConstants.STRING);

XML 看起来像

 <cam:message xmlns="urn:xxx:1.0:logging">
         <cam:response>
           <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
               <soapenv:Header xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
                   <Info xmlns="urn:xxx:1.0:xxx.core.xxx.Service1">
                      <property name="response">some value</property>
                 </Info>
                 <Info xmlns="urn:xxx:1.0:xxx.core.xxx.Service2">
                      <property name="response">i am interested in this value</property>
                 </Info>
               </soapenv:Header>
           </soapenv:Envelope>
     </cam:response>
</cam:message>

所以标签&lt;Info xmlns="urn:xxx:1.0:xxx.core.xxx.Service2"&gt;拥有自己的命名空间。我的程序没有为此返回值。同样有很多 Info 标签。我对命名空间以 Service2 结尾的第二个 Info 标记感兴趣。

【问题讨论】:

    标签: java xml xpath


    【解决方案1】:

    您当前的 XPath 表达式仅匹配具有 no 命名空间 uri 的 Info 和 property 元素。

    您必须将urn:...Service2-namespace 添加到您的NamespaceContext 内部类:

    public String getNamespaceURI(String prefix) {
        if ("cam".equals(prefix))
           // like abvce
        else if ("s2".equals(prefix))
           return "urn:xxx:1.0:xxx.core.xxx.Service2";
        else
           return XMLConstants.NULL_NS_URI;
    }
    

    并相应地限定 XPath 中的 Infoproperty 步骤,使用前缀 s2

    xpath.compile("/cam:message/cam:response/soapenv:Envelope/soapenv:Header/s2:Info/s2:property[@name='response']/text()");
    

    除此之外,您的代码和 XML 文件中存在错误:

    a) 在创建 DocumentBuilder之后让 DocumentBuilderFactory 感知命名空间。改为写:

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setNamespaceAware(true);
    DocumentBuilder builder = factory.newDocumentBuilder();
    

    b) 您的 XML 使用前缀 cam,该前缀未在根元素中正确声明。改为写:

    <cam:message xmlns:cam="urn:xxx:1.0:logging">
        ....
    

    【讨论】:

    • @wero.i 做了您建议的更改.. 谢谢。但我也看不到它的工作原理
    • @Shiv 也许你需要进一步调整你的 XPath 表达式。
    • 我是这个 xpath 的新手。虽然我的路径对我来说看起来简单而合乎逻辑,但不知道它为什么不起作用。任何可能的帮助
    • @wero。谢谢。在构建器创建之前添加命名空间感知将 issue.wrt 修复为更改我无法控制的 xml。但仅此一项更改就解决了我的问题。谢谢阿根
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-23
    • 2016-03-24
    • 1970-01-01
    • 2012-11-22
    • 2020-04-16
    相关资源
    最近更新 更多