2017-08-06 75 views
1

我有如下的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

回答

1

我使用下面的方法將在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

1

嘗試你的代碼,它看起來對我來說工作正常。下面是我做的

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