How to read XML using XPath in Java

后端 未结 8 1375
无人及你
无人及你 2020-11-21 05:38

I want to read XML data using XPath in Java, so for the information I have gathered I am not able to parse XML according to my requirement.

here is what I want to do

8条回答
  •  迷失自我
    2020-11-21 05:55

    This shows you how to

    1. Read in an XML file to a DOM
    2. Filter out a set of Nodes with XPath
    3. Perform a certain action on each of the extracted Nodes.

    We will call the code with the following statement

    processFilteredXml(xmlIn, xpathExpr,(node) -> {/*Do something...*/;});
    

    In our case we want to print some creatorNames from a book.xml using "//book/creators/creator/creatorName" as xpath to perform a printNode action on each Node that matches the XPath.

    Full code

    @Test
    public void printXml() {
        try (InputStream in = readFile("book.xml")) {
            processFilteredXml(in, "//book/creators/creator/creatorName", (node) -> {
                printNode(node, System.out);
            });
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    private InputStream readFile(String yourSampleFile) {
        return Thread.currentThread().getContextClassLoader().getResourceAsStream(yourSampleFile);
    }
    
    private void processFilteredXml(InputStream in, String xpath, Consumer process) {
        Document doc = readXml(in);
        NodeList list = filterNodesByXPath(doc, xpath);
        for (int i = 0; i < list.getLength(); i++) {
            Node node = list.item(i);
            process.accept(node);
        }
    }
    
    public Document readXml(InputStream xmlin) {
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            return db.parse(xmlin);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    private NodeList filterNodesByXPath(Document doc, String xpathExpr) {
        try {
            XPathFactory xPathFactory = XPathFactory.newInstance();
            XPath xpath = xPathFactory.newXPath();
            XPathExpression expr = xpath.compile(xpathExpr);
            Object eval = expr.evaluate(doc, XPathConstants.NODESET);
            return (NodeList) eval;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    private void printNode(Node node, PrintStream out) {
        try {
            Transformer transformer = TransformerFactory.newInstance().newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
            StreamResult result = new StreamResult(new StringWriter());
            DOMSource source = new DOMSource(node);
            transformer.transform(source, result);
            String xmlString = result.getWriter().toString();
            out.println(xmlString);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    

    Prints

    Fosmire, Michael
    
    Wertz, Ruth
    
    Purzer, Senay
    

    For book.xml

    
      
        
          Fosmire, Michael
          Michael
          Fosmire
        
        
          Wertz, Ruth
          Ruth
          Wertz
        
        
          Purzer, Senay
           Senay
           Purzer
        
      
      
        Critical Engineering Literacy Test (CELT)
      
    
    

提交回复
热议问题