是你所描述听起来不那么难的问题:如果您可以放心地假设这些书元素的每一个孩子都是一个“项目”,然后就可以调用你的“项目处理程序”为每个孩子。
下面是伪代码(我认为)会工作,假设<书>总是只有文档的顶级元素:
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
}
}
}
即使伪代码,这是过于简单和丑陋。另一种方法,但可能会因您的需要而被夸大的方法是将您的应用程序分解为多个类,在您到达某些元素的开始或结束时传递责任。
例如:让我们假设一个BookHandler的实例被传递给parser.parse()调用,以处理顶级元素。然后:
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);
}
}
}
该方案提供了更多的灵活性和更多的重用可能性。例如,潜在的“书籍”元素现在可以是其他元素的子元素,例如“部门”,而不需要对这些类进行任何更改。
伪代码不是完美无缺的。 (一方面,我想更多地考虑处理程序关闭的位置 - 在父类或孩子中。另一方面,我可能已经过度地将节点引用给父母和孩子这些课程)。但我希望它能给你提供一些你可以开始使用的想法。
我不明白你的问题,你能详细解释一下吗? – blindstuff 2010-11-17 16:45:33
对不起,我想解析XML文档(上面的那个)此刻我正在使用SAX解析器,但那不起作用,因为当我识别元素时:Element item = books.getChild(“item”)null返回 - 因为XML文档没有'item'标签,但'item1','item2','item3'... – Marqs 2010-11-17 17:28:21