2017-08-06 5 views
1

J'ai un XML comme ci-dessous:Comment analyser un XML complexe en utilisant 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> 

Je veux extraire la valeur « getParty » de l'étiquette en utilisant XPath XML Parser. J'utilise le ci-dessous mon expression:

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

Comment puis-je écrire le code java précis et complet pour ce qui précède? Je veux juste extraire la valeur pour <InquiryType>getParty</InquiryType>.

+0

J'utilise ci-dessous: NodeList xpathNodeList = (NodeList) expression.evaluate (doc, XPathConstants.NODESET); \t System.out.println ("longueur xpathNodeList est:" + xpathNodeList.getLength()); Cependant, il imprimer longueur 0. – Som

+0

Essayez d'utiliser 'XPathConstants.STRING' –

+0

Il dit: Exception dans le thread "principal" java.lang.ClassCastException: java.lang.String incompatible avec org.w3c.dom.NodeList – Som

Répondre

1

J'utilise la méthode ci-dessous:

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: Je pourrais imprimer l'élément racine correctement, mais pas le "xpathNodeList.item (0))". Il imprime null. – Som

+0

mon code fonctionne correctement après avoir supprimé les espaces d'espace de noms. – Som

1

En essayant votre code, il semble que cela fonctionne bien pour moi. Voici ce que je faisais

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)); 
} 

Avec test.xml contenant exactement le xml que vous utilisez

<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, par défaut, le générateur de document n'est pas conscient de l'espace de noms, donc vous pouvez vous en passer avec le chemin utilisé s'il n'y a qu'un espace de noms par défaut et aucun préfixe utilisé dans le XML. D'autres implémentations comme Saxon veulent cependant un DOM sensible à l'espace de noms je pense. –

+1

Je suis arrivé là où je me trompais. J'utilisais la ligne ci-dessous: dbFactory.setNamespaceAware (true); Lorsque j'ai commenté le code, cela fonctionne très bien. – Som