using SAX parser, how do you parse an xml file which has same name tags but in different elements?

Srinivas picture Srinivas · Aug 26, 2011 · Viewed 18k times · Source

Is it possible to give path expressions in SAX parser? I have an XML file which has a few same name tags, but they are in different element. Is there any way to differentiate between them. Here is the XML:

<Schools>
    <School>
        <ID>335823</ID> 
        <Name>Fairfax High School</Name> 
        <Student>
            <ID>4195653</ID>
            <Name>Will Turner</Name>
        </Student>
        <Student>
            <ID>4195654</ID>
            <Name>Bruce Paltrow</Name>
        </Student>
        <Student>
            <ID>4195655</ID>
            <Name>Santosh Gowswami</Name>
        </Student>
    </School>
    <School>
        <ID>335824</ID> 
        <Name>FallsChurch High School</Name> 
        <Student>
            <ID>4153</ID>
            <Name>John Singer</Name>
        </Student>
        <Student>
            <ID>4154</ID>
            <Name>Shane Warne</Name>
        </Student>
        <Student>
            <ID>4155</ID>
            <Name>Eddie Diaz</Name>
        </Student>
    </School>
</Schools>

I want to differentiate between the Name and Id of a student from the name and ID of a school.

Thanks for the response:

I have created a student pojo which has the following fields- school_id,school_name, student_id and student_name and getter and setter methods for them. This is my temporary parser implementation. When i parse the xml, I need to put the values of school name, id , student name, id in the pojo and return it. Can you tell me on how I should implement the stack for the differentiation. This is my parser framework::

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class HandleXML extends DefaultHandler {

    private student info;
    private boolean school_id = false;
    private boolean school_name = false;
    private boolean student_id = false;
    private boolean student_name = false;
    private boolean student = false;
    private boolean school = false;


    public HandleXML(student record) {
        super();
        this.info = record;
        school_id = false;
        school_name = false;
        student_id = false;
        student_name = false;
        student = false;
        school = false;
    }

    @Override
    public void startElement(String uri, String localName,
            String qName, Attributes attributes)
            throws SAXException {
    if (qName.equalsIgnoreCase("student")) {
            student = true;
        }
    if (qName.equalsIgnoreCase("school")) {
            school_id = true;
        }
    if (qName.equalsIgnoreCase("school_id")) {
            school_id = true;
        }
    if (qName.equalsIgnoreCase("student_id")) {
            student_id = true;
        }
    if (qName.equalsIgnoreCase("school_name")) {
            school_name = true;
        }
    if (qName.equalsIgnoreCase("student_name")) {
            student_name = true;
        }
    }

    @Override
    public void endElement(String uri, String localName,
            String qName)
            throws SAXException {
    }

    @Override
    public void characters(char ch[], int start, int length)
            throws SAXException {

        String data = new String(ch, start, length);

    }
}

Answer

Jim Garrison picture Jim Garrison · Aug 26, 2011

In a SAX parser you are given each element in document order. You have to maintain a stack to track nesting (push onto the stack when handling startElement, and pop for endElement). You can differentiate the different <Name> elements by what is currently on the stack.

Alternatively, just keep a variable that tells you if you've encountered a <School> tag or <Student> tag to tell you which type of <Name> you are seeing.