It's not clear to me that this is necessarily better, but you could maintain a currentList
field in your ParseXML
class for the current list to manipulate:
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class ParseXML extends DefaultHandler {
private Library lib;
private List<Book> extraBooks = new ArrayList<Book>();
private List<Book> currentList = extraBooks;
public ParseXML(String file) throws ParserConfigurationException, SAXException, IOException {
parse(file);
}
private void parse(String file) throws ParserConfigurationException, SAXException, IOException {
final SAXParserFactory factory = SAXParserFactory.newInstance();
final SAXParser parser = factory.newSAXParser();
parser.parse(file, this);
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (qName.equals("read") || qName.equals("unread"))
currentList = extraBooks;
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (qName.equals("library")) {
String name = attributes.getValue("name");
lib = new Library(name);
}
else if (qName.equals("read")) {
currentList = lib.getReadBooks();
}
else if (qName.equals("unread")) {
currentList = lib.getUnreadBooks();
}
else if (qName.equals("book")) {
String id = attributes.getValue("id");
String lang = attributes.getValue("lang");
String title = attributes.getValue("title");
String author = attributes.getValue("author");
currentList.add(new Book(id, lang, title, author));
}
}
/**
* @return the lib
*/
public Library getLibrary() {
return lib;
}
}
As a mildly different approach, you could of course keep both lists and the library name as fields in your handler, and create the Library
in the endElement
method using all the data collected.
Note: (obsolete) In this code I used the field extraBooks
to allow for <book>
tags occurring outside the <read>
and <unread>
tags. It's just a little safer than just setting currentList
to null
in the endElement
method. I hate NullPointerException
.
Update:
You don't need the throwaway field extraBooks
.
You can accomplish the same null-safety by changing the initialization of currentList
to
private List<Book> currentList = new ArrayList<Book>();
and the endElement
method to
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (qName.equals("read") || qName.equals("unread"))
currentList = new ArrayList<Book>();
}