如何使用XPath

如何使用XPath

问题描述:

我有如下的XML解析复杂的XML:如何使用XPath

<Service xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns="someurl" xsi:schemaLocation="someurl Sample.xsd"> 
    <RequestControl> 
     <requestID>100129</requestID> 
     <Control> 
      <requesterName>Admin</requesterName> 
      <requesterLanguage>100</requesterLanguage> 
     </Control> 
    </RequestControl> 
    <Inquiry> 
     <InquiryType>getParty</InquiryType> 
     <InquiryParam> 
      <Param name="PartyId">854850029276139020</Param> 
     </InquiryParam> 
    </Inquiry> 
</Service> 

我想提取使用XPath XML解析器从标签值“getParty”。我正在使用下面作为我的表达式:

expression = xPath.compile("/Service/Inquiry/InquiryType/text()"); 

我该如何编写上述准确和完整的java代码?我只想提取<InquiryType>getParty</InquiryType>的值。

+0

我使用如下: 节点列表xpathNodeList =(NodeList)expression.evaluate(doc,XPathConstants.NODESET); System.out.println(“xpathNodeList length is:”+ xpathNodeList.getLength()); 但是其打印长度为0 – Som

+0

尝试使用'XPathConstants.STRING' –

+0

它说: 异常在线程“主要” java.lang.ClassCastException:java.lang.String中不符合org.w3c.dom.NodeList – Som

我使用下面的方法将在XML的test.xml:

public static String inputXmlXPathParser(String inputXml){ 


     //==================================================X-Path Parser =============================================================// 

     String transactionName = StringUtils.EMPTY; 

     try { 

      DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); 
      dbFactory.setNamespaceAware(true); 
      DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); 
      Document doc = dBuilder.parse(new InputSource(new StringReader(inputXml))); 
      doc.getDocumentElement().normalize(); 

      System.out.println("Root element :" + doc.getDocumentElement().getNodeName()); 

      XPathFactory xPathfactory = XPathFactory.newInstance(); 
      XPath xpath = xPathfactory.newXPath(); 
      XPathExpression expression = xpath.compile("/Service/Inquiry/InquiryType/text()"); 
      NodeList xpathNodeList = (NodeList) expression.evaluate(doc, XPathConstants.NODESET); 
      System.out.println("InquiryType is : " +xpathNodeList.item(0)); 

     } catch (ParserConfigurationException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (SAXException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (XPathExpressionException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     }  


     return transactionName; 

    } 
+0

@jeanr:我可以正确地打印根元素,但不是“xpathNodeList.item(0))”。它打印null。 – Som

+0

我删除命名空间的东西后,我的代码工作正常。 – Som

尝试你的代码,它看起来对我来说工作正常。下面是我做的

public static void main(String ... args) throws ParserConfigurationException, IOException, SAXException, XPathExpressionException { 
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
    DocumentBuilder builder = factory.newDocumentBuilder(); 
    Document doc = builder.parse(System.getProperty("user.dir") + "/src/main/resources/test.xml"); 
    XPathFactory xPathfactory = XPathFactory.newInstance(); 
    XPath xpath = xPathfactory.newXPath(); 
    XPathExpression expression = xpath.compile("/Service/Inquiry/InquiryType/text()"); 
    NodeList xpathNodeList = (NodeList) expression.evaluate(doc, XPathConstants.NODESET); 
    System.out.println("InquiryType is : " +xpathNodeList.item(0)); 
} 

的时候只有你正在使用

<Service xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="someurl" xsi:schemaLocation="someurl Sample.xsd"> 
<RequestControl> 
    <requestID>100129</requestID> 
    <Control> 
     <requesterName>Admin</requesterName> 
     <requesterLanguage>100</requesterLanguage> 
    </Control> 
</RequestControl> 
<Inquiry> 
    <InquiryType>getParty</InquiryType> 
    <InquiryParam> 
     <Param name="PartyId">854850029276139020</Param> 
    </InquiryParam> 
</Inquiry> 
</Service> 
+1

@DanielHaley,默认情况下文档构建器不支持名称空间,所以如果在XML中只有一个默认名称空间并且没有使用前缀,那么您可能会忽略所使用的路径。但是像Saxon这样的其他实现需要一个名称空间感知的DOM,我认为。 –

+1

我得到了错误的地方。我正在使用下面的行: dbFactory.setNamespaceAware(true); 当我注释掉代码时,它可以正常工作。 – Som