2014-06-26 131 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

相关问题