2013-12-09 99 views
1

我經常想要在整個子樹中存在某個元素時使用XPATH表達式過濾一個元素,我想知道是否可以讓xpath表達式匹配所有結果。下面的表達式僅評估爲true如果是匹配的第一個元素(Cd[2]相同,但總Cd[3]評估完整子樹的存在

xpath::evaluate(" //CuorS/Cd[ starts-with(./*/@Name], 'Dog')]") 
<CuorS> 
    <Cd> 
    <Ani Name="CatOne" /> 
    <Bodi Name="Fish" /> 
    </Cd> 
    <Cd> 
    <Ani Name="DogOne" /> 
    <Bodi Name="Fish" /> 
    </Cd> 
    <Cd> 
    <Ani Name="Owl" /> 
    <Bodi Name="DogTwo" /> 
    </Cd> 
</CuorS> 

我知道我可以制訂表達

xpath::evaluate("//CuorS/Cd/*[ starts-with(./@Name], 'Dog')]/..") 

以匹配所有,但我正在尋找一個過濾器表達式來匹配存在:'如果該子樹中有一個匹配元素'。我可以評估結果序列的功能,而不僅僅是一個?

謝謝!

回答

1

怎麼樣XPath表達式:

//CuorS/Cd[ count(./*[starts-with(@Name, 'Dog')]) >= 1] 

這只是計算匹配的子節點(那些帶有「狗」開始)。 因此它匹配每個至少有一個子節點符合該條件的Cd。

正如你所看到的,當你嵌套條件塊時它變得非常簡單。通過嵌套它們,您也可以按照您似乎要求的方式對節點序列進行評估(不完全理解您在那裏實現的目標)。

下面是從XPATH輸出(給你的樣品輸入):

<Cd> 
    <Ani Name="DogOne"/> 
    <Bodi Name="Fish"/> 
    </Cd> 
    <Cd> 
    <Ani Name="Owl"/> 
    <Bodi Name="DogTwo"/> 
    </Cd> 
+0

爲什麼要計算元素來檢查是否有內容?非空序列評估爲真。 –

+0

因爲我喜歡東西不要讓人驚訝。是的,空節點列表評估爲false,非空列表爲真,但這是閱讀此xPath需要了解的另一部分知識。爲什麼不通過寫出你真正關心的條件來明確表達你的意思。讓其他人更容易瞭解發生了什麼。 – Matthias

+0

然後最好使用'not(empty(...))'或類似的東西,這樣更具可讀性(如果沒有優化)可能快得多:'count(...)'需要計算所有項目,評估'空(...)'或只評估它爲一個布爾值可以在第一次匹配後停止。無論如何:這是一個非常非常常用的模式,每個人都使用'// foo [bar]',這完全一樣。 –

1

只需推動謂:

xpath::evaluate("//CuorS/Cd[*[starts-with(./@Name]], 'Dog')]") 

這將匹配CuorS的所有鎘的孩子,有一個子元素一個以Dog開頭的名字。根據您使用XPath處理器和編程語言,你甚至可以生成一個布爾值:

xpath::evaluate("boolean(//CuorS/Cd[*[starts-with(./@Name]], 'Dog')])") 

如果結果序列是空的,這會產生錯誤,如果有至少一個元素,它將返回true。