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

} 
+0

没有冒犯,但代码看起来非常复杂,我.. – 2011-03-02 03:04:42

+0

@ vtd-xml-author - 我已经切换代码来扩展DefaultHandler而不是直接实现ContentHandler,这应该使代码更容易理解。链接内容处理程序是标准SAX解析中非常强大的机制。 – 2011-03-02 20:16:41

+0

错误,此代码不起作用。 – Wayne 2011-10-31 10:54:24

请编辑您的帖子,包括一个示例XML和什么意味着描述由“跳节点” 。

由于您的解析器获取每个事件的控制权,您可以根据您所需的任何标准选择不做任何事情。如果你想跳过整个子树,当你遇到子树的开始元素并清除结束元素处的标志时,你必须设置一个全局标志;然后使用该标志来控制所包含节点的处理。

+0

我添加了xml,我想跳过“钠”元素 – London 2010-07-28 21:05:37

+0

好吧,“跳过”是什么意思?在一个SAX解析器中,您可以控制...您可以手动解析事件并可以执行任何您想要的操作。你会得到每个标签的start-element事件,并且当标签名称是“sodium”时,你可以编写逻辑来返回,忽略数据。编辑您的帖子并显示您迄今在Java中尝试过的内容。 – 2010-07-28 21:14:34

不幸的是,我没有权利评论其他答案。我只是想纠正“韦恩”的错误主张,即布莱斯的回答“不起作用”。我试过这段代码,它确实输出了示例数据中的所有值,只是钠的含量 - 我认为这正是OP所寻求的。