Parse xml file using vtd-xml

后端 未结 1 760
执笔经年
执笔经年 2021-01-07 02:15

How can i parse a xml file like the following using vtd-xml in java or C ?



  
相关标签:
1条回答
  • 2021-01-07 02:40

    I guess some of this depends on how you want to parse the file.

    Here's a "non-production" example which uses a few techniques which are useful, including:

    • XPath select (just using "/*" here)
    • look through all sibling nodes
    • look down through child nodes
    • extract node attributes into a map using AutoPilot

    Hope it helps

    package scce;
    
    import com.ximpleware.AutoPilot;
    import com.ximpleware.NavException;
    import com.ximpleware.VTDGen;
    import com.ximpleware.VTDNav;
    import com.ximpleware.XPathEvalException;
    import com.ximpleware.XPathParseException;
    import java.io.File;
    import java.io.IOException;
    import java.util.LinkedHashMap;
    import java.util.Map;
    
    /**
     *
     * @author David
     */
    public class VTDParserExample {
    
        VTDGen vg;
        VTDNav vn;
    
        public VTDParserExample() {
            vg = new VTDGen();    
        }
    
        public void parseAndPrint() throws NavException {
    
            int level = 0;
    
            for(boolean el = (vn != null); 
                        el == true ;
                        el = vn.toElement(VTDNav.NEXT_SIBLING)) {
    
                printTag(vn, level);
    
                parseAndPrintChildren(level);                
            }
    
        } 
    
         private void parseAndPrintChildren(int level) throws NavException {
    
            vn.push();
    
            for(boolean el = vn.toElement(VTDNav.FIRST_CHILD); 
                        el == true ;
                        el = vn.toElement(VTDNav.NEXT_SIBLING)) {
    
                printTag(vn, level + 1);
    
                parseAndPrintChildren(level + 1);                
            }
    
            vn.pop();
    
        }
    
        public VTDNav loadFile(String filePath) throws IOException {
    
            File fDoc = new File(filePath);
    
            if (fDoc != null && fDoc.exists()) {
                System.out.println("loadFile file exists ["+filePath+"]");
    
                vg.clear();
                if (vg.parseFile(filePath, true)) {
                    vn = vg.getNav();
                }
            }
            else {
                throw new IOException("File ["+filePath+"] invalid");
            }             
    
            if (vn == null) {                
                throw new IOException("Cannot parse file ["+filePath+"]");
            }
    
            return vn;
        }
    
        public void getElementsByXpath() {
    
            AutoPilot ap = new AutoPilot(vn);
    
            try
            {
                String xpQ = "/*";
    
                ap.selectXPath(xpQ);    
                if (ap.evalXPathToBoolean()) {
                    ap.evalXPath();
                }
                else {
                    System.out.println(this.getClass()+".getAllElements evalXPathToBoolean["+ap.evalXPathToBoolean()+"]");
                }
            }
            catch(XPathParseException | XPathEvalException | NavException e) {
                e.printStackTrace();
            }            
    
        }
    
        private void loadAttributeMap(VTDNav nav, Map<String, String>amap) {      
    
            nav.push();
    
            try {
                AutoPilot apAtt = new AutoPilot(nav);
                apAtt.selectXPath("@*");
    
                int j=-1;
                while ((j=apAtt.evalXPath())!=-1) {
                    String name = nav.toString(j);
                    String val = nav.toString(j+1);
    
                    amap.put(name, val);
                }                     
            }
            catch(XPathParseException | XPathEvalException | NavException e) {
                e.printStackTrace();
            }
    
            nav.pop();        
        }     
    
        private void printTag(VTDNav vn, int level) throws NavException {
    
            String tag = vn.toString(vn.getCurrentIndex());
            System.out.print("Level ["+level+"] Tag ["+tag+"]");
    
            Map<String, String>amap = new LinkedHashMap<String, String>();
    
            loadAttributeMap(vn, amap);
    
            for (String aname: amap.keySet()) {
                String aval = amap.get(aname);
    
                System.out.print(" @"+aname+"="+aval);
            }
            System.out.print("\n");
        }
    
        public static void main(String[] args) {
    
            VTDParserExample vp = new VTDParserExample();
    
            try {
    
                vp.loadFile("src/scce/famedoro.xml");                                     
                vp.getElementsByXpath();
                vp.parseAndPrint();
    
            }
            catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
    

    Which produces the following output:

    loadFile file exists [src/scce/famedoro.xml]
    Level [0] Tag [StockReport]
    Level [1] Tag [Article] @Code=027783012 @Height=35 @Width=36 @Length=136 @TotalPacks=4 @AvailablePacks=4 @StockReturnPacks=4 @BlockedPacks=0 @NextExpiryDate=2015-01-17
    Level [2] Tag [Machine] @Number=1 @TotalPacks=4 @AvailablePacks=4 @StockReturnPacks=4 @BlockedPacks=0 @NextExpiryDate=2015-01-17
    Level [1] Tag [Article] @Code=025349109 @Height=36 @Width=37 @Length=129 @TotalPacks=6 @AvailablePacks=6 @StockReturnPacks=6 @BlockedPacks=0 @NextExpiryDate=2015-01-17
    Level [2] Tag [Machine] @Number=1 @TotalPacks=6 @AvailablePacks=6 @StockReturnPacks=6 @BlockedPacks=0 @NextExpiryDate=2015-01-17
    Level [1] Tag [Article] @Code=039154327 @Height=0 @Width=0 @Length=0 @TotalPacks=0 @AvailablePacks=0 @StockReturnPacks=0 @BlockedPacks=0 @NextExpiryDate=
    Level [1] Tag [Article] @Code=932654167 @Height=57 @Width=99 @Length=137 @TotalPacks=27 @AvailablePacks=27 @StockReturnPacks=27 @BlockedPacks=0 @NextExpiryDate=2014-04-17
    Level [2] Tag [Machine] @Number=1 @TotalPacks=16 @AvailablePacks=16 @StockReturnPacks=16 @BlockedPacks=0 @NextExpiryDate=2015-01-17
    Level [2] Tag [Machine] @Number=2 @TotalPacks=11 @AvailablePacks=11 @StockReturnPacks=11 @BlockedPacks=0 @NextExpiryDate=2014-04-17
    

    Adding example with AutoPilot loop (rather than purely node based as above) doesn't mix these very well

    package scce;
    
    import com.ximpleware.AutoPilot;
    import com.ximpleware.NavException;
    import com.ximpleware.VTDGen;
    import com.ximpleware.VTDNav;
    import com.ximpleware.XPathEvalException;
    import com.ximpleware.XPathParseException;
    import java.io.File;
    import java.io.IOException;
    import java.util.LinkedHashMap;
    import java.util.Map;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    /**
     *
     * @author David
     */
    public class VTDParserExample {
    
        VTDGen vg;
        VTDNav vn;
        AutoPilot ap;
    
        public VTDParserExample() {
            vg = new VTDGen();    
        }
    
        public void parseAndPrint() throws NavException {
    
            int level = 0;
    
            for(boolean el = (vn != null); 
                        el == true ;
                        el = vn.toElement(VTDNav.NEXT_SIBLING)) {
    
                printTag(vn, level);
    
                parseAndPrintChildren(level);                
            }
    
        } 
    
         private void parseAndPrintChildren(int level) throws NavException {
    
            vn.push();
    
            for(boolean el = vn.toElement(VTDNav.FIRST_CHILD); 
                        el == true ;
                        el = vn.toElement(VTDNav.NEXT_SIBLING)) {
    
                printTag(vn, level + 1);
    
                parseAndPrintChildren(level + 1);                
            }
    
            vn.pop();
    
        }
    
        private VTDNav loadFile(String filePath) throws IOException {
    
            File fDoc = new File(filePath);
    
            if (fDoc != null && fDoc.exists()) {
                System.out.println("loadFile file exists ["+filePath+"]");
    
                vg.clear();
                if (vg.parseFile(filePath, true)) {
                    vn = vg.getNav();
                }
            }
            else {
                throw new IOException("File ["+filePath+"] invalid");
            }             
    
            if (vn == null) {                
                throw new IOException("Cannot parse file ["+filePath+"]");
            }
    
            return vn;
        }
    
        public boolean getElementsByXpath() {
            boolean found = false;
    
            ap = new AutoPilot(vn);
    
            try
            {
                String xpQ = "//Machine";
    
                ap.selectXPath(xpQ);    
                if (ap.evalXPathToBoolean()) {
                    found = true;
                }
                else {
                    System.out.println(this.getClass()+".getAllElements evalXPathToBoolean["+ap.evalXPathToBoolean()+"]");
                }
            }
            catch(XPathParseException e) {
                e.printStackTrace();
            }            
    
            return found;
        }
    
        private void loadAttributeMap(VTDNav nav, Map<String, String>amap) {      
    
            nav.push();
    
            try {
                AutoPilot apAtt = new AutoPilot(nav);
                apAtt.selectXPath("@*");
    
                int j=-1;
                while ((j=apAtt.evalXPath())!=-1) {
                    String name = nav.toString(j);
                    String val = nav.toString(j+1);
    
                    amap.put(name, val);
                }                     
            }
            catch(XPathParseException | XPathEvalException | NavException e) {
                e.printStackTrace();
            }
    
            nav.pop();        
        }     
    
        private void printTag(VTDNav vn, int level) throws NavException {
    
            String tag = vn.toString(vn.getCurrentIndex());
            System.out.print("Level ["+level+"] Tag ["+tag+"]");
    
            Map<String, String>amap = new LinkedHashMap<String, String>();
    
            loadAttributeMap(vn, amap);
    
            for (String aname: amap.keySet()) {
                String aval = amap.get(aname);
    
                System.out.print(" @"+aname+"="+aval);
            }
            System.out.print("\n");
        }
    
        public static void main(String[] args) {
    
            VTDParserExample vp = new VTDParserExample();
    
            try {
    
                vp.loadFile("src/scce/famedoro.xml");
                if (vp.getElementsByXpath()) {
                     vp.parseAndPrintAP();                
                }
            }
            catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    
        private void parseAndPrintAP() {
            int level = 0;
            int result = -1;
    
            try {
                while((result = ap.evalXPath())!=-1){
                    printTag(vn, level);
    
                    parseAndPrintChildren(level);                
    
                }
            } catch (XPathEvalException | NavException ex) {
                ex.printStackTrace();
            }
        }
    
    }
    

    This - with different XPath set to "//Machine" produces:

    loadFile file exists [src/scce/famedoro.xml]
    Level [0] Tag [Machine] @Number=1 @TotalPacks=4 @AvailablePacks=4 @StockReturnPacks=4 @BlockedPacks=0 @NextExpiryDate=2015-01-17
    Level [0] Tag [Machine] @Number=1 @TotalPacks=6 @AvailablePacks=6 @StockReturnPacks=6 @BlockedPacks=0 @NextExpiryDate=2015-01-17
    Level [0] Tag [Machine] @Number=1 @TotalPacks=16 @AvailablePacks=16 @StockReturnPacks=16 @BlockedPacks=0 @NextExpiryDate=2015-01-17
    Level [0] Tag [Machine] @Number=2 @TotalPacks=11 @AvailablePacks=11 @StockReturnPacks=11 @BlockedPacks=0 @NextExpiryDate=2014-04-17
    
    0 讨论(0)
提交回复
热议问题