使用sax跳过节点
解析时是否可以跳过节点以及这个skippedEntity
与它有什么关系?使用sax跳过节点
考虑这个XML:
<?xml version="1.0"?>
<nutrition>
<daily-values>
<total-fat units="g">65</total-fat>
<saturated-fat units="g">20</saturated-fat>
<cholesterol units="mg">300</cholesterol>
<sodium units="mg">2400</sodium>
<carb units="g">300</carb>
<fiber units="g">25</fiber>
<protein units="g">50</protein>
</daily-values>
</nutrition>
我想跳过“钠”元素
你可以做类似如下:
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.XMLReader;
public class Demo {
public static void main(String[] args) throws Exception {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
xr.setContentHandler(new MyContentHandler(xr));
xr.parse("input.xml");
}
}
MyContentHandler
这个类是负责处理XML文档。当你点击一个你想忽略的节点时,你可以交换IgnoringContentHandler,它将吞下该节点的所有事件。
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
public class MyContentHandler extends DefaultHandler {
private XMLReader xmlReader;
public MyContentHandler(XMLReader xmlReader) {
this.xmlReader = xmlReader;
}
public void startElement(String uri, String localName, String qName,
Attributes atts) throws SAXException {
if ("sodium".equals(qName)) {
xmlReader.setContentHandler(new IgnoringContentHandler(xmlReader,
this));
} else {
System.out.println("START " + qName);
}
}
public void endElement(String uri, String localName, String qName)
throws SAXException {
System.out.println("END " + qName);
}
public void characters(char[] ch, int start, int length)
throws SAXException {
System.out.println(new String(ch, start, length));
}
}
IgnoringContentHandler
当IgnoringContentHandler做吞咽控制向后传递到主ContentHandler事件。
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
public class IgnoringContentHandler extends DefaultHandler {
private int depth = 1;
private XMLReader xmlReader;
private ContentHandler contentHandler;
public IgnoringContentHandler(XMLReader xmlReader, ContentHandler contentHandler) {
this.contentHandler = contentHandler;
this.xmlReader = xmlReader;
}
public void startElement(String uri, String localName, String qName,
Attributes atts) throws SAXException {
depth++;
}
public void endElement(String uri, String localName, String qName)
throws SAXException {
depth--;
if(0 == depth) {
xmlReader.setContentHandler(contentHandler);
}
}
}
请编辑您的帖子,包括一个示例XML和什么你意味着描述由“跳节点” 。
由于您的解析器获取每个事件的控制权,您可以根据您所需的任何标准选择不做任何事情。如果你想跳过整个子树,当你遇到子树的开始元素并清除结束元素处的标志时,你必须设置一个全局标志;然后使用该标志来控制所包含节点的处理。
我添加了xml,我想跳过“钠”元素 – London 2010-07-28 21:05:37
好吧,“跳过”是什么意思?在一个SAX解析器中,您可以控制...您可以手动解析事件并可以执行任何您想要的操作。你会得到每个标签的start-element事件,并且当标签名称是“sodium”时,你可以编写逻辑来返回,忽略数据。编辑您的帖子并显示您迄今在Java中尝试过的内容。 – 2010-07-28 21:14:34
不幸的是,我没有权利评论其他答案。我只是想纠正“韦恩”的错误主张,即布莱斯的回答“不起作用”。我试过这段代码,它确实输出了示例数据中的所有值,只是钠的含量 - 我认为这正是OP所寻求的。
没有冒犯,但代码看起来非常复杂,我.. – 2011-03-02 03:04:42
@ vtd-xml-author - 我已经切换代码来扩展DefaultHandler而不是直接实现ContentHandler,这应该使代码更容易理解。链接内容处理程序是标准SAX解析中非常强大的机制。 – 2011-03-02 20:16:41
错误,此代码不起作用。 – Wayne 2011-10-31 10:54:24