2017-05-08 66 views
0

我正在解析Java應用程序中的自定義XML配置文件。我正在嘗試使用SAX解析器,主要是因爲我需要使用行號報告配置中的錯誤。跳過Java中SAX解析中元素的內容

有很多代碼樣本的網上實現處理類,事情似乎正常的處理相當簡單的 - 例如,http://tutorials.jenkov.com/java-xml/sax-example.html

但在我的情況下,有時我需要跳過下的整個樹元素:

<sampledocument> 
    <sampletag> 
     <process/> 
     <these/> 
     <tags/> 
    </sampletag> 
    <sampletag skip="yes"> 
     <do_not> 
     <process/> 
     <these/> 
     <tags/> 
    </sampletag> 
<sampledocument> 

後來增加:另外,我只知道是否在運行時跳過。在一定程度上人爲的例子,我需要打開一個文件來處理<sampletag>下的標籤,如果沒有找到該文件,而不是對其進行處理:

<sampledocument> 
    <sampletag file="file1"> 
     <process/> 
     <these/> 
     <tags/> 
     <if_file1_exists/> 
    </sampletag> 
    <sampletag file="file2"> 
     <process/> 
     <these/> 
     <tags/> 
     <if_file2_exists/> 
    </sampletag> 
<sampledocument> 

當然,我可以跟蹤在處理程序跳過代碼,但這有點尷尬。我可以在startElement()方法中告訴SAX跳過這個元素的內容嗎?

回答

1

編寫一個過濾器類,以便位於SAX解析器和現有ContentHandler之間的管道上。你可以通過擴展XMLFilterImpl來實現。這個過濾器應該有一個整數變量skipDepth,最初爲零。

在startElement中,如果您識別想要深度跳過的元素,或者skipDepth> 0,則增加skipDepth。

在endElement中,如果skipDepth> 0,則遞減skipDepth。

在所有事件處理程序,傳遞事件上下來的管道(通過調用super.xxx())當且僅當skipDepth == 0

如果你想聰明,你可以寫這個過濾器以通用的方式,因此它需要一個參數,它是一個回調函數,它接受節點名稱和屬性並返回一個指示是否跳過該元素的布爾值。然後,您可以在下次想要跳過元素時重新使用代碼,但跳過條件不同。

+0

謝謝!但是,與簡單地維護ContentHandler中的skipDepth有什麼不同?在我的真實任務中,ContentHandler必須在確定是否跳過樹之前實際處理元素,因此如果我有單獨的過濾器,則ContentHandler必須觸發跳過。 –

+0

SAX代碼總是最好寫成一個管道,每個可分離任務的管道中只有一步。否則,你很快就會在ContentHandler中產生意大利麪代碼(你已經說過它「有點尷尬」)。通過正確構建的流水線,您最終得到易於修改和調試的可維護,可重用的代碼;如果你把所有東西都放在ContentHandler中,你最終會得到不可維護的混亂。當然,如果你的例子與真實任務不同,那麼我不能告訴你如何分解真正任務中的功能。 –

+0

我修改了示例以在運行時測試文件。真正的代碼驗證配置的正確性,解釋它如何驗證它會產生一個很長的問題,但它是對一個單獨的類的調用 - 與檢查文件有點類似。 –