使用sax跳过节点

时间:2010-07-28 20:32:39

标签: java xml sax

解析时是否可以跳过节点?这个skippedEntity与它有什么关系?

考虑这个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>

我想跳过“钠”元素

3 个答案:

答案 0 :(得分:7)

您可以执行以下操作:

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);
        }
    }

}

答案 1 :(得分:3)

请编辑您的帖子,以便通过“跳过节点”包含示例XML和的含义说明。

由于您的解析器可以控制每个事件,因此您可以根据所需的任何条件选择不执行任何操作。如果要跳过整个子树,则必须在遇到子树的start元素时设置全局标志,并在结束元素处清除标志;然后使用该标志来控制所包含节点的处理。

答案 2 :(得分:1)

不幸的是,我没有权利评论其他答案。我只是想纠正“韦恩”错误的断言,即布莱斯的答案“不起作用”。我已经尝试过这个代码,它确实输出了示例数据中的所有值,除了Sodium之外 - 我认为这正是OP所寻求的。