The problem that you've described doesn't sound all that hard: If you can safely assume that every child of the books element is an "item", then you can invoke your "item handler" for each child.
Here's pseudocode that (I think) would work, assuming that <books> is always and only the top-level element of the document:
class BookHandler extends DefaultHandler {
public void startElement(String namespaceURI, String localName,
String qName, Attributes atts) {
if (localName.equals("books") {
// Don't need to do anything with the top level element
return;
}
else {
handleItem(namespaceURI, localName, qName, atts);
}
}
public void endElement(String namespaceURI, String localName, String qName) {
if localName.equals("books") {
// Stop parsing and exit.
}
else {
// Stop parsing one item
}
}
private void handleItem(String namespaceURI, String localName,
String qName, Attributes atts) {
// Handle one item, including handling the "name" and
// "type" child attributes
if (localName.equals("name") {
// handle the name
}
else if (localName.equals("type") {
// handle the type
}
}
}
Even as pseudocode, that's over-simplistic and ugly. An alternative approach, but which may be overblown for your needs, is to decompose your application into multiple ContentHandler
classes, passing off responsibility as you reach the beginning or ending of certain elements.
For example: Let's assume that an instance of BookHandler is passed in to the parser.parse() call, to handle the top-level elements. Then:
class BookHandler extends DefaultHandler {
private ContentHandler m_parentHandler;
private ContentHandler m_childHandler = null;
// ... == appropriate args for the DefaultHandler constructor
public BookHandler(ContentHandler parent, Attributes atts, ...) {
super(...);
m_parentHandler = parent;
parent.getXMLReader().setHandler(this);
}
public void startElement(String namespaceURI, String localName,
String qName, Attributes atts) {
if (localName.equals("books") {
// Don't need to do anything with the top level element
return;
}
else {
// Assume it's a new item element. (Note: ItemHandler's constructor
// changes the parser's ContentHandler.)
m_childHandler = new ItemHandler(this, atts, ...);
}
}
public void endElement(String namespaceURI, String localName, String qName) {
if localName.equals("books") {
// Stop parsing and exit.
}
else {
// Note that this won't be called for "item" elements, UNLESS the
// ItemHandler's endElement method explicitly invokes this method.
// Stop parsing one item
}
}
}
class ItemHandler extends DefaultHandler {
private ContentHandler m_parentHandler;
// ItemInfo is a class that holds all info about the current item
private ItemInfo m_ItemInfo = null;
// ... == appropriate args for the DefaultHandler constructor
public ItemHandler(ContentHandler parent, Attributes atts, ...) {
super(...);
m_parentHandler = parent;
m_ItemInfo = new ItemInfo(atts);
parent.getXMLReader().setHandler(this);
}
public void startElement(String namespaceURI, String localName,
String qName, Attributes atts) {
if (localName.equals("name") {
// Handle the name. Update the current item as needed.
}
else if (localName.equals("type") {
// Handle the type. Update the current item as needed.
}
}
public void endElement(String namespaceURI, String localName, String qName) {
if localName.equals("name" || localName.equals("type") {
// Do nothing (?)
}
else {
// Stop parsing the current item;
// let the parent class handle the next element.
getXMLReader().setHandler(m_parentHandler);
// OPTIONALLY -- depending on your app's needs -- call the
// parent's endElement() method to let it know that we reached
// the end of an item.
m_parentHandler.endElement(namespaceURI, localName, qName);
}
}
}
This scheme offers more flexibility, and more possibilities for reuse. For example, potentially the "books" element could now be a child of some other element, say "departments", without requiring much if any changes to these classes.
The pseudo-code isn't perfect by any means. (For one thing, I'd want to think some more about where the handlers are switched off -- in the parent class, or in the child. For another thing, I may have gone overboard in saving references to both parents and children in these classes.) But I hope it gives you ideas that you can start working with.