2013-08-26 203 views
1

使用XPath(.NET),我試圖選擇不包含任何文本節點的所有節點。查找沒有任何文本節點的所有節點

鑑於此文件:

<root> 
    <node1> 
    <node1a>Node 1A</node1a> 
    </node1> 
    <node2>Node 2</node2> 
    <node3> 
    <node3a>Node 3A</node3a> 
    <node3b></node3b> 
    </node3> 
    <node4></node4> 
    <node5> 
    <node5A></node5A> 
    </node5> 
</root> 

我tyring得到節點:

<node3b></node3b> 

<node4></node4> 

<node5> 
    <node5A></node5A> 
</node5> 

注意重疊的子樹被合併,所以node5A不應單獨返回。

我希望它可以拉的伎倆,但由於某種原因(這可能是顯而易見的,當有人指出它)不:

//*[count(//text()) = 0] 

注:我使用XPath tester嘗試的事情出。

回答

1

假設你的結果例子真的是你想要的東西(這是不是完全按照在冠軍語句)以上

//*[count(.//text()) = 0] 

或首選的方式的建議

//*[not(.//text())] 

不工作結果不是你所期望的

<node3b /> 
<node4 /> 
<node5> 
    <node5A /> 
</node5> 
<node5A /> <!-- this node is not present in your example --> 

如果你想要的是所有s沒有任何文本節點ubtrees不包括在其他所得的子樹的溶液是這樣的一個

//*[not(.//text())][not(ancestor::*[not(.//text())])] 

第二謂詞從結果所有這些具有至少一個祖先已經包含在結果中的節點

+0

那裏好挑剔;)我確實需要合併子樹,所以我編輯了這個問題。 –

2

精氨酸......和剛發佈的時候,解決作物起來:

//*[count(.//text()) = 0] 

說明:條件count(//text()) = 0計數從根本上,這始終是大於零的所有文本節點。要從當前節點計數,我需要以點爲前綴:count(.//text()) = 0

請注意@jvverde正確地指出節點可以在結果集中多次出現。所以這個表達式是不是我提的條件完全匹配,如node5A是有兩次:

<node3b></node3b> 

<node4></node4> 

<node5> 
    <node5A></node5A> 
</node5> 

<node5A></node5A> 
1

你也可以使用//*[.='']儘可能空元素應該有空字符串值。

+2

這需要除去首先計算數據字符串,並且可能比計算文本節點更昂貴。 –

0

您也可以使用更簡單,可讀

//*[not(.//text())] 

,或者如果您希望通過empty(...)更換not(...)

兩者都已經過優化,所以即使簡單的XPath實現也應該能夠以「快速失敗」的方式實現它們(找到一個文本節點,將謂詞評估爲false)。

+0

在我意識到我的表情中罪魁禍首之前,我做了一些「不」的試驗。我會嘗試你的建議,所以你可能會得到獎勵;) –

相關問題