2014-06-26 185 views
3

考慮下面的XML文檔...的XPath發現沒有其他元素的元素引用它們

<r> 
    <e id="a" /> 
    <e id="b" /> 
    <e id="c" /> 
    <x ref="#b" /> 
</r> 

...我怎麼能寫一個XPath 1.0表達式,查找所有<e>元素沒有一個<x>元素引用它們?在這個例子中,結果應該是#a#c

基於this question我試過//e[ not(//x[@ref=concat("#",@id)]) ],但這並不能省略引用的元素:

# Ruby code using Nokogiri 
puts doc.xpath('//e[ not(//x[@ref=concat("#",@id)]) ]') 
#=> <e id="a"/> 
#=> <e id="b"/> 
#=> <e id="c"/> 

有一種使用在發現設爲進一步查詢中的其他元素的其他屬性的值的屬性的方法?

+0

請注意,在Ruby中,您可以通過'doc.xpath('// e')實現多重傳遞。 doc.at(「// x [@ref ='## {e ['id']}']」)}';這個問題是關於一個XPath表達式來找到正確的集合。 – Phrogz

回答

3

從這個XML

<r> 
    <e id="a" /> 
    <e id="b" /> 
    <e id="c" /> 
    <x ref="#b" /> 
</r> 

這個XPath

//e[ not(//x/@ref=concat("#",@id)) ] 

將選擇

<e id="a"/> 
<e id="c"/> 

按要求。

+0

賓果!謝謝。您是否碰巧在XPath規範中提供了一個可以描述屬性解決方案的範圍規則的參考?而且......哇,我從來沒有在謂詞之外看到過一個平等的斷言。 – Phrogz

+2

[** XPath謂詞**](http://www.w3.org/TR/xpath/#predicates)是相對於上下文節點定義的。你遇到的問題是,當你真的只希望'x'是'@ ref'的上下文時,你同時建立'x'作爲'@ ref' **和**'@ id'的上下文。和'e'是'@ id'的上下文。 – kjhughes

+0

@Progrog我認爲謂詞中的相等_is_,它和'// e [not(concat(「#」,@id)= // x/@ ref)]'幾乎相同,我剛纔在看到我被毆打之前作爲回答發佈,但是顯示了相等性將'concat'的結果與'// x/@ ref'節點集進行比較。 [布爾和比較規範的一部分](http://www.w3.org/TR/xpath/#booleans)在這裏也非常相關。 – matt

相關問題