Reputation: 62624
I am using the SAX parser in java. I am not sure:
1) What classes I need for this kind of situation? I am guessing I want to have Classes for (please let me know if my thoughts are completely wrong): -FosterHome (Contains an Arraylist of Family and Child) -Family (Contains ArrayList for Child and a String fro parent) -Child (contains ArrayList for ChildID)
2) How to handle this situation in the startElement and endElement method
What complicates is due to the ChildID appearing in both the ChildList and the RemainingChildList. Appreciate anyone who can help me out.
<FosterHome>
<Orphanage>Happy Days Daycare</Orphanage>
<Location>Apple Street</Location>
<Families>
<Family>
<Parent>Adams</ParentID>
<ChildList>
<ChildID>Child1</ChildID>
<ChildID>Child2</ChildID>
</ChildList>
</Family>
<Family>
<Parent>Adams</ParentID>
<ChildList>
<ChildID>Child3</ChildID>
<ChildID>Child4</ChildID>
</ChildList>
</Family>
</Families>
<RemainingChildList>
<ChildID>Child5</ChildID>
<ChildID>Child6</ChildID>
</RemainingChildList>
</FosterHome>
Upvotes: 0
Views: 233
Reputation: 96
To handle ChildID elements from different parent elements, you can save the current state when enter startElement() handler method for ChildList and RemainingChildList respectively. Then, when you enter endElement() handler method for a ChildID, you process the current ChildID depending on the saved state (for example populate appropriate fields in your FosterHome class).
For example:
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import java.io.CharArrayReader;
import java.io.CharArrayWriter;
import java.io.IOException;
public class XmlParser {
static void parse(String xml, Handler handler) throws SAXException, ParserConfigurationException, IOException
{
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
XMLReader reader = saxParserFactory.newSAXParser().getXMLReader();
reader.setContentHandler(handler);
reader.parse(new InputSource(new CharArrayReader(xml.toCharArray())));
}
static class Handler extends DefaultHandler {
CharArrayWriter contents = new CharArrayWriter();
static enum STATE { Family, Remaining }
STATE state;
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
{
if (qName.equals("ChildList"))
state = STATE.Family;
else if (qName.equals("RemainingChildList"))
state = STATE.Remaining;
else if (qName.equals("ChildID"))
contents.reset();
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException
{
if (qName.equals("ChildID"))
System.out.println(contents.toString() + " [" + state + "]");
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException
{
contents.write(ch, start, length);
}
}
public static void main(String[] args) throws Exception
{
String xml = "<FosterHome>\n" +
"<Orphanage>Happy Days Daycare</Orphanage>\n" +
"<Location>Apple Street</Location>\n" +
"<Families>\n" +
" <Family>\n" +
" <ParentID>Adams</ParentID>\n" +
" <ChildList>\n" +
" <ChildID>Child1</ChildID>\n" +
" <ChildID>Child2</ChildID>\n" +
" </ChildList>\n" +
" </Family>\n" +
" <Family>\n" +
" <ParentID>Adams</ParentID>\n" +
" <ChildList>\n" +
" <ChildID>Child3</ChildID>\n" +
" <ChildID>Child4</ChildID>\n" +
" </ChildList>\n" +
" </Family>\n" +
"</Families>\n" +
"<RemainingChildList>\n" +
"<ChildID>Child5</ChildID>\n" +
"<ChildID>Child6</ChildID>\n" +
"</RemainingChildList>\n" +
"</FosterHome>";
parse(xml, new Handler());
}
}
Upvotes: 1
Reputation: 53598
If your document is small, the first thing I'd say is: don't use the SAX parser, use the DOM parser instead.
If your document is large, or read "on the fly", then use the SAX parser. The downside of the SAX parser is that you are responsible for coming up with the code equivalent of the XML, so if you want every element in its own object, you're going to have to define all those classes yourself.
class FosterHome {
String orphanage;
ArrayList<Family> families = new ArrayList<Family>();
ArrayList<Child> remainingChildren = new ArrayList<Child>();
}
class Family {
String parent;
ArrayList<Child> children = new ArrayList<Child>();
public Family(String _parent) { parent = _parent; }
}
class Child {
String id;
public Child(String _id) { id = _id;}
}
etc.
And then write event handlers for SAX events whenever it sees opening and closing tags, which keep track of what the current open elements are, adding objects to them as they're found, and closing them off as closing tags are found.
It's a chore, but well-documented in various places, such as on http://totheriver.com/learn/xml/xmltutorial.html
Upvotes: 2