How to read XML using XPath in Java

后端 未结 8 1373
无人及你
无人及你 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 06:19

    Read XML file using XPathFactory, SAXParserFactory and StAX (JSR-173).

    Using XPath get node and its child data.

    public static void main(String[] args) {
        String xml = "<soapenv:Body xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'>"
                + "<Yash:Data xmlns:Yash='http://Yash.stackoverflow.com/Services/Yash'>"
                + "<Yash:Tags>Java</Yash:Tags><Yash:Tags>Javascript</Yash:Tags><Yash:Tags>Selenium</Yash:Tags>"
                + "<Yash:Top>javascript</Yash:Top><Yash:User>Yash-777</Yash:User>"
                + "</Yash:Data></soapenv:Body>";
        String jsonNameSpaces = "{'soapenv':'http://schemas.xmlsoap.org/soap/envelope/',"
                + "'Yash':'http://Yash.stackoverflow.com/Services/Yash'}";
        String xpathExpression = "//Yash:Data";
    
        Document doc1 = getDocument(false, "fileName", xml);
        getNodesFromXpath(doc1, xpathExpression, jsonNameSpaces);
        System.out.println("\n===== ***** =====");
        Document doc2 = getDocument(true, "./books.xml", xml);
        getNodesFromXpath(doc2, "//person", "{}");
    }
    static Document getDocument( boolean isFileName, String fileName, String xml ) {
        Document doc = null;
        try {
    
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setValidating(false);
            factory.setNamespaceAware(true);
            factory.setIgnoringComments(true);
            factory.setIgnoringElementContentWhitespace(true);
    
            DocumentBuilder builder = factory.newDocumentBuilder();
            if( isFileName ) {
                File file = new File( fileName );
                FileInputStream stream = new FileInputStream( file );
                doc = builder.parse( stream );
            } else {
                doc = builder.parse( string2Source( xml ) );
            }
        } catch (SAXException | IOException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }
        return doc;
    }
    
    /**
     * ELEMENT_NODE[1],ATTRIBUTE_NODE[2],TEXT_NODE[3],CDATA_SECTION_NODE[4],
     * ENTITY_REFERENCE_NODE[5],ENTITY_NODE[6],PROCESSING_INSTRUCTION_NODE[7],
     * COMMENT_NODE[8],DOCUMENT_NODE[9],DOCUMENT_TYPE_NODE[10],DOCUMENT_FRAGMENT_NODE[11],NOTATION_NODE[12]
     */
    public static void getNodesFromXpath( Document doc, String xpathExpression, String jsonNameSpaces ) {
        try {
            XPathFactory xpf = XPathFactory.newInstance();
            XPath xpath = xpf.newXPath();
    
            JSONObject namespaces = getJSONObjectNameSpaces(jsonNameSpaces);
            if ( namespaces.size() > 0 ) {
                NamespaceContextImpl nsContext = new NamespaceContextImpl();
    
                Iterator<?> key = namespaces.keySet().iterator();
                while (key.hasNext()) { // Apache WebServices Common Utilities
                    String pPrefix = key.next().toString();
                    String pURI = namespaces.get(pPrefix).toString();
                    nsContext.startPrefixMapping(pPrefix, pURI);
                }
                xpath.setNamespaceContext(nsContext );
            }
    
            XPathExpression compile = xpath.compile(xpathExpression);
            NodeList nodeList = (NodeList) compile.evaluate(doc, XPathConstants.NODESET);
            displayNodeList(nodeList);
        } catch (XPathExpressionException e) {
            e.printStackTrace();
        }
    }
    
    static void displayNodeList( NodeList nodeList ) {
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node node = nodeList.item(i);
            String NodeName = node.getNodeName();
    
            NodeList childNodes = node.getChildNodes();
            if ( childNodes.getLength() > 1 ) {
                for (int j = 0; j < childNodes.getLength(); j++) {
    
                    Node child = childNodes.item(j);
                    short nodeType = child.getNodeType();
                    if ( nodeType == 1 ) {
                        System.out.format( "\n\t Node Name:[%s], Text[%s] ", child.getNodeName(), child.getTextContent() );
                    }
                }
            } else {
                System.out.format( "\n Node Name:[%s], Text[%s] ", NodeName, node.getTextContent() );
            }
    
        }
    }
    static InputSource string2Source( String str ) {
        InputSource inputSource = new InputSource( new StringReader( str ) );
        return inputSource;
    }
    static JSONObject getJSONObjectNameSpaces( String jsonNameSpaces ) {
        if(jsonNameSpaces.indexOf("'") > -1)    jsonNameSpaces = jsonNameSpaces.replace("'", "\"");
        JSONParser parser = new JSONParser();
        JSONObject namespaces = null;
        try {
            namespaces = (JSONObject) parser.parse(jsonNameSpaces);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return namespaces;
    }
    

    XML Document

    <?xml version="1.0" encoding="UTF-8"?>
    <book>
    <person>
      <first>Yash</first>
      <last>M</last>
      <age>22</age>
    </person>
    <person>
      <first>Bill</first>
      <last>Gates</last>
      <age>46</age>
    </person>
    <person>
      <first>Steve</first>
      <last>Jobs</last>
      <age>40</age>
    </person>
    </book>
    

    Out put for the given XPathExpression:

    String xpathExpression = "//person/first";
    /*OutPut:
     Node Name:[first], Text[Yash] 
     Node Name:[first], Text[Bill] 
     Node Name:[first], Text[Steve] */
    
    String xpathExpression = "//person";
    /*OutPut:
         Node Name:[first], Text[Yash] 
         Node Name:[last], Text[M] 
         Node Name:[age], Text[22] 
         Node Name:[first], Text[Bill] 
         Node Name:[last], Text[Gates] 
         Node Name:[age], Text[46] 
         Node Name:[first], Text[Steve] 
         Node Name:[last], Text[Jobs] 
         Node Name:[age], Text[40] */
    
    String xpathExpression = "//Yash:Data";
    /*OutPut:
         Node Name:[Yash:Tags], Text[Java] 
         Node Name:[Yash:Tags], Text[Javascript] 
         Node Name:[Yash:Tags], Text[Selenium] 
         Node Name:[Yash:Top], Text[javascript] 
         Node Name:[Yash:User], Text[Yash-777] */
    

    See this link for our own Implementation of NamespaceContext

    0 讨论(0)
  • 2020-11-21 06:21

    Here is an example of processing xpath with vtd-xml... for heavy duty XML processing it is second to none. here is the a recent paper on this subject Processing XML with Java – A Performance Benchmark

    import com.ximpleware.*;
    
    public class changeAttrVal {
        public  static  void main(String s[]) throws VTDException,java.io.UnsupportedEncodingException,java.io.IOException{
            VTDGen vg = new VTDGen();
            if (!vg.parseFile("input.xml", false))
                return;
            VTDNav vn = vg.getNav();
            AutoPilot ap = new AutoPilot(vn);
            XMLModifier xm = new XMLModifier(vn);
            ap.selectXPath("/*/place[@id=\"p14\" and   @initialMarking=\"2\"]/@initialMarking");
            int i=0;
            while((i=ap.evalXPath())!=-1){
                xm.updateToken(i+1, "499");// change initial marking from 2 to 499
            }
            xm.output("new.xml");
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题