2012-08-27 90 views
3

以下XML如何在Java中使用XPath作爲節點訪問CDATA?

<a>foo <![CDATA[ MyCData]]> baz</a>  

使用this網上的XPath測試儀與XPath表達式/a/text(),我回來的所有文字

foo <![CDATA[ MyCData]]> baz 

(這是結構爲三個節點,我們可以看到使用/a/text()[2],返回baz。)

但是,使用javax.xml.xpath.XPath, CData an d最後的文本節點是而不是完全返回。我使用foo獲得單個節點,而文本<![CDATA[ MyCData]]> baz的其餘部分則不可用。無論XPath如何處理XML結構,如果我們根本無法訪問節點,那就是一個錯誤。

但是,如果我設置isCoalescing(真)的DocumentBuilderFactory,它加到所有的文字和CDATA節點爲一體。我最終可能會使用它,但它會將CData轉換爲輸出中的轉義文本,即使標準允許,這看起來也很難看。另外,我更希望能夠將CData分別作爲某種節點來處理,無論是「只是」文本節點,還是某種特殊類型的CData節點。

順便說一句,如果在CDATA是它的父元素的只有內容,不帶空格或前面其他文本,一個普通的文本內容的XPath成功地檢索它,即使其默認isCoalescingfalse)。因此,我們看到Java XPath始終返回第一個文本節點,並且只返回第一個文本節點。

當我審視我的DOM文檔的完整DOM樹,isCoalescing在其默認情況下,我發現,CDATA節被表示爲自己的類型CDATA段的節點,這是偉大的,但如何我可以在XPath中訪問此節點嗎?

+1

也許這有助於:http://stackoverflow.com/questions/4184858/is-there-a-single-xpath-expression-i-can-use-to-navigate-xml-in-a-cdata-section – Sal

+0

謝謝,但是有關XML _inside_ CData的討論。我只想要CData!在其他XPath引擎中,CData只是一個文本節點,但不是Java中描述的。 –

回答

2

網上的XPath測試儀得到它錯了,我很害怕。根據XPath數據模型,<a>元素具有單個文本節點孩子,其字符串值爲"foo MyCDATA baz";沒有第二個文本節點,因此對第二個文本節點的請求不應該返回任何內容。

XPath數據模型以認爲CDATA僅僅是輸入數據,以避免必須轉義特殊字符的一種方便的方法; CDATA的存在不會影響XML的含義或信息內容,因此它不能提供給應用程序。

+0

好吧,如果Java XPath返回單個節點* foo MyCData baz *,那將會很棒。但實際上,它返回單個節點* foo *而沒有其他節點。 –

+0

顯然setCoalescing(true)給出了你描述的結果。但是在合併錯誤的情況下,Java XPath引擎做了什麼?它似乎沒有產生一種替代結構,而只是在所有文本上「放棄」,而不是第一個節點。 –

+0

Saxon XPath引擎爲您提供包含所有數據的單個文本節點,而不管DOM是否合併。試一試。 (更好的是,不要使用DOM:切換到更好的樹模型,比如JDOM或XOM)。 –