Java中的XPath查询不返回任何元素

我正在开发一个使用 SOAP 作为通信协议的 Web 服务:我通过使用 Spring Boot 和 Spring WS 来实现这一点。

有时,我可能需要通过请求的标头发送一些内容,并且我希望能够通过 XPath 表达式恢复该信息。

这是我到目前为止所做的:


        ByteArrayOutputStream buffer = new ByteArrayOutputStream();

        WebServiceMessage message = messageContext.getRequest();


        Source s = messageContext.getRequest().getPayloadSource();

        messageContext.getRequest().writeTo(buffer);

        String payload = buffer.toString(java.nio.charset.StandardCharsets.UTF_8.name());

        System.out.println(payload);

        InputStream is = new ByteArrayInputStream(payload.getBytes());

在下面的代码片段中,我阅读了获取后端接收的整个请求。之后,我以前所做的是将所有这些转换为一个 SOAPHeader 对象,该对象包含我想要的所有内容......除了我根本无法进行任何 XPath 查询以及我真正需要的元素下树。

因此,我决定以下列方式继续该代码片段


        //-------

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

        DocumentBuilder builder = factory.newDocumentBuilder();

        Document doc = builder.parse(new java.io.ByteArrayInputStream(payload.getBytes()));

        XPath xpath = XPathFactory.newInstance().newXPath();

现在,这是我发送的请求示例


<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:it="it.niuma.mscsoapws.ws">

   <soapenv:Header>

       <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">

       <wsse:UsernameToken wsu:Id="UsernameToken-3967AEB46D733EF6E2154990461080350">

       <wsse:Username>TAVI</wsse:Username>

       <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>

       <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-

这是我的问题:Java 端的 XPath 表达式不返回任何内容,而其他工具(例如这个)正确评估表达式并返回一些内容。在 Java 中唯一能正确计算的 XPath 表达式是 //*,仅此而已。我错过了什么?


潇湘沐
浏览 184回答 2
2回答

米琪卡哇伊

我知道上次我在 java 中使用 XPath 时遇到了命名空间问题,必须添加一个 namespaceContext 才能使其工作。如果要在 XPath 中使用soapenv 命名空间,则需要“注册”它。你可以在下面找到我当时所做的事情。可能不是 100% 干净,但仍可能对您有所帮助&nbsp; &nbsp; xpath.setNamespaceContext(new NamespaceContext() {&nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; public String getNamespaceURI(String prefix) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if("soapenv".equals(prefix)){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return "http://schemas.xmlsoap.org/soap/envelope/";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }else{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return null;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; public String getPrefix(String namespaceURI) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return null;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; public Iterator getPrefixes(String namespaceURI) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return null;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; });编辑:用我对您的代码的修复进行了测试运行,这是您期望看到的吗?found node -> Header (namespace: http://schemas.xmlsoap.org/soap/envelope/)

动漫人物

这是使一切正常工作所缺少的唯一代码行&nbsp; &nbsp; &nbsp; &nbsp; factory.setNamespaceAware(true);所以整个工作代码是&nbsp; &nbsp; &nbsp; &nbsp; DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();&nbsp; &nbsp; &nbsp; &nbsp; factory.setNamespaceAware(true);&nbsp; &nbsp; &nbsp; &nbsp; DocumentBuilder builder = factory.newDocumentBuilder();&nbsp; &nbsp; &nbsp; &nbsp; Document doc = builder.parse(new java.io.ByteArrayInputStream(payload.getBytes()));&nbsp; &nbsp; &nbsp; &nbsp; XPath xpath = XPathFactory.newInstance().newXPath();&nbsp; &nbsp; &nbsp; &nbsp; xpath.setNamespaceContext(new NamespaceContext() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public String getNamespaceURI(String prefix) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if("soapenv".equals(prefix)){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return "http://schemas.xmlsoap.org/soap/envelope/";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }else{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return null;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public String getPrefix(String namespaceURI) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return null;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public Iterator getPrefixes(String namespaceURI) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return null;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; XPathExpression expr = xpath.compile("//soapenv:Envelope//soapenv:Header//text()[normalize-space()]");&nbsp; &nbsp; &nbsp; &nbsp; Object result = expr.evaluate(doc, XPathConstants.NODESET);&nbsp; &nbsp; &nbsp; &nbsp; NodeList nodes = (NodeList) result;
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java