简体   繁体   中英

How to skip the parent tag, based on the value of a child tag in XML Parsing using SAX Parser

<root>
<parent>
    <child1> 30</child1>
    <child2> 30</child2>
    <child3> 30</child3>
</parent>
 <parent>
    <child1> 20</child1>
    <child2> 30</child2>
    <child3> 30</child3>
</parent>
 <parent>
    <child1> 30</child1>
    <child2> 30</child2>
    <child3> 30</child3>
</parent>
</root>

I am really new to the world of coding and to sax parsing.. Consider the above XML, what I need is. .. based on the value of the tag child1, if it is greater than 20, only then I would want to parse the remaining child tags(child2 and child3), otherwise I would want to move on to the next parent tag.

Could anyone pls suggest what would be the ideal way to do it?

Something like that:

...
private boolean skipChildren;
private StringBuilder buf = new StringBuilder();
...

@Override
public void startElement(String uri, String localName, String qName,
        Attributes attributes) throws SAXException {
    if (qName.equals("parent")) {
        skipChildren = false;
        ...
    } else if (qName.equals("child1")) {
        buf.setLength(0);
        ...
    } else if (qName.startsWith("child")) {
        if (!skipChildren) {
            buf.setLength(0);
            ...
        }
    }
}

@Override
public void endElement(String uri, String localName, String qName)
        throws SAXException {
    if (qName.equals("parent")) {
        ...
    } else if (qName.equals("child1")) {
        int value = Integer.parseInt(buf.toString().trim());
        if (value <= 20) {
            skipChildren = true;
        }
        ...
    } else if (qName.startsWith("child")) {
        if (!skipChildren) {
            int value = Integer.parseInt(buf.toString().trim());
            doSomethingWith(value);
        }
    }
}

@Override
public void characters(char[] ch, int start, int length) {
    if (!skipChildren) {
        buf.append(ch, start, length);
    }
}

Below is the code to perform your task with vtd-xml , it is the state of art in xml processing technology, and is a lot more efficient and simpler to write than SAX... the key is by using xpath expression to filter out only the nodes of interest... read this paper that gives you loads of reasons to avoid SAX parsing whenever possible

Processing XML with Java – A Performance Benchmark

import com.ximpleware.*;
public class conditionalSelection {
    public static void main(String s[]) throws VTDException{
        VTDGen vg = new VTDGen();
        if(!vg.parseFile("d:\\xml\\condition.xml", false)) // disable namespace
            return;
        VTDNav vn = vg.getNav();
        AutoPilot ap = new AutoPilot(vn);
        ap.selectXPath("/root/parent[child1>20]"); // the xpath selecting all parents with child1>20
        int i=0,j=0;
        while((i=ap.evalXPath())!=-1){
            // now move the cursor to child2 and child3
            if(vn.toElement(VTDNav.FC,"child2")){
                j = vn.getText();
                if (j!=-1)//make sure the text node exist
                    System.out.println(" child2's text node is ==>"+ vn.toString(j));
                vn.toElement(VTDNav.P);
            }
            if(vn.toElement(VTDNav.FC,"child3")){
                j = vn.getText();
                if (j!=-1)//make sure the text node exist
                    System.out.println(" child3's text node is ==>"+ vn.toString(j));
                vn.toElement(VTDNav.P);
            }
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM