Java XPath Compile无法使用唯一命名空间查询标记

时间:2015-09-11 16:17:20

标签: java xml xpath

我在这里经历了很多问题,但似乎没有解决我面临的问题

我有一个带有唯一命名空间的标签。仅仅是那个标签。我介绍了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>

因此标记<Info xmlns="urn:xxx:1.0:xxx.core.xxx.Service2">具有自己的名称空间。我的程序没有为此返回值。类似地,有许多Info标签。我感兴趣的是第二个Info标签,其命名空间以Service2结尾。

请帮助

1 个答案:

答案 0 :(得分:2)

您当前的XPath表达式仅将Info和属性元素与 no 命名空间uri匹配。

您必须将dataframe - 命名空间添加到urn:...Service2内部类:

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

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

a)在创建DocumentBuilder之后,使DocumentBuilderFactory名称空间感知。改为写:

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

b)您的XML使用未在根元素中正确声明的前缀DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); DocumentBuilder builder = factory.newDocumentBuilder(); 。改为写:

cam