【问题标题】:Can't get value with XPath in Soap XML无法在 Soap XML 中使用 XPath 获得价值
【发布时间】:2015-12-19 13:23:44
【问题描述】:

我有 XML,我想找到 price 标签和 code

的路径
  <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
     <getProductDetailsResponse xmlns="http://warehouse.example.com/ws">
       <getProductDetailsResult>
         <productID>12345</productID>
         <productName>Стакан граненый</productName>
         <description>Стакан граненый. 250 мл.</description>
         <price>9.95</price>
         <currency>
             <code>840</code>
             <alpha3>USD</alpha3>
             <sign>$</sign>
             <name>US dollar</name>
             <accuracy>2</accuracy>
         </currency>
         <inStock>true</inStock>
       </getProductDetailsResult>
     </getProductDetailsResponse>
   </soap:Body>
</soap:Envelope>

如果我删除命名空间,我可以获得值的路径-xmlns="http://warehouse.example.com/ws"... 路径是 - /soap:Envelope/soap:Body/getProductDetailsResponse/getProductDetailsResult/price/text()

但服务器只返回命名空间。

如何获取值?

提前致谢

【问题讨论】:

  • 可悲的是,这又是一个说明 SOAP 过度使用的例子。您需要在 XPATH 查询中添加命名空间。执行此操作的方法因您运行 XPath(php、C#、java、xsl)的方式而异。你用什么来解析你的 SOAP XML?
  • @WilliamWalseth 我尝试将命名空间添加到 XPath,但它不起作用。我在 PL/SQL (Oracle) 中解析 xml
  • 类似这篇文章的内容解释了如何。读完之后,您就会明白为什么 SOAP 太过分了。 community.oracle.com/thread/2553686?start=0&tstart=0
  • 如果您可以在 PL/SQL 中应用 XSL 转换,请运行本文中的转换,然后您可以使用常规 XPath,而无需命名空间。 stackoverflow.com/questions/5268182/…
  • @WilliamWalseth 感谢威廉,您的建议。这个问题我也自己回答。

标签: xml xpath


【解决方案1】:

您可以从 XML 中获取所有值。

例如,如果你想获取&lt;price&gt;标签值使用

/soap:Envelope/soap:Body/*/*/*[4]/text()

或代码标签 - 使用

/soap:Envelope/soap:Body/*/*/*/*[1]/text()

【讨论】:

    【解决方案2】:

    如果你使用java,你必须管理前缀:

    String expression="your path here !"
    
    XPath xpath = XPathFactory.newInstance().newXPath();
    NamespaceContext ctx = new NamespaceContext() {
        public String getNamespaceURI(String prefix) {
            if (prefix == null) throw new NullPointerException("Null prefix");
            return XMLConstants.XML_NS_URI; //   .NULL_NS_URI;
        }
        public String getPrefix(String uri) {
            throw new UnsupportedOperationException();
        }
        public Iterator getPrefixes(String uri) {
            throw new UnsupportedOperationException();
        }
    };
    xpath.setNamespaceContext(ctx);
    XPathExpression expr = xpath.compile(expression) ; 
    

    expression="/Envelope/Body/getProductDetailsResponse/getProductDetailsResult/price";
    

    expression="/Envelope/Body/getProductDetailsResponse/getProductDetailsResult/currency/code";
    

    它的工作原理是这样的:

    NodeList nodes  = (NodeList) expr.evaluate(document, XPathConstants.NODESET);
    
      for (int k = 0; k < nodes.getLength(); k ++) {
          Node nodeSegment = nodes.item(k);
          if (nodeSegment.getNodeType() == Node.ELEMENT_NODE) {
              Element eElement = (Element) nodeSegment;
              System.out.println("TAG="+eElement.getTagName());              
              System.out.println("TEXT CONTENT="+eElement.getTextContent());
          }
    

    你可以得到其他关于前缀的解决方案:NamespaceContext and using namespaces with XPath

    【讨论】:

      猜你喜欢
      • 2019-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多