2010-07-28 72 views
4

解析時是否可以跳過節點以及這個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> 

我想跳過「鈉」元素

回答

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

} 
+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

3

請編輯您的帖子,包括一個示例XML和什麼意味着描述由「跳節點」 。

由於您的解析器獲取每個事件的控制權,您可以根據您所需的任何標準選擇不做任何事情。如果你想跳過整個子樹,當你遇到子樹的開始元素並清除結束元素處的標誌時,你必須設置一個全局標誌;然後使用該標誌來控制所包含節點的處理。

+0

我添加了xml,我想跳過「鈉」元素 – London 2010-07-28 21:05:37

+0

好吧,「跳過」是什麼意思?在一個SAX解析器中,您可以控制...您可以手動解析事件並可以執行任何您想要的操作。你會得到每個標籤的start-element事件,並且當標籤名稱是「sodium」時,你可以編寫邏輯來返回,忽略數據。編輯您的帖子並顯示您迄今在Java中嘗試過的內容。 – 2010-07-28 21:14:34

1

不幸的是,我沒有權利評論其他答案。我只是想糾正「韋恩」的錯誤主張,即布萊斯的回答「不起作用」。我試過這段代碼,它確實輸出了示例數據中的所有值,只是鈉的含量 - 我認爲這正是OP所尋求的。