给出如下所示的结构,其中一个ClaimsIdentity
元素可以包含任意数量的RootFolder
元素,包括嵌套的Folder
元素,我想选择所有Folder
包含至少一个后代RootFolder
元素的元素,其所有祖先File
元素(如果有)的Folder
属性都设置为true。
visible
以下XPath表达式不能解决问题,因为它包括最后两个<Root>
<!-- This should be included -->
<RootFolder>
<Folder visible="true">
<File />
</Folder>
<Folder visible="false">
<File />
</Folder>
</RootFolder>
<!-- This should be included -->
<RootFolder>
<Folder visible="true">
<Folder visible="true">
<File />
</Folder>
</Folder>
</RootFolder>
<!-- This should not be included -->
<RootFolder>
<Folder visible="false">
<File />
</Folder>
</RootFolder>
<!-- This should not be included -->
<RootFolder>
<Folder visible="false">
<Folder visible="true">
<File />
</Folder>
</Folder>
</RootFolder>
<!-- This should not be included -->
<RootFolder>
<Folder visible="true">
<Folder visible="false">
<File />
</Folder>
</Folder>
</RootFolder>
</Root>
元素。
RootFolder
鉴于http://courses.ischool.berkeley.edu/i290-14/s05/lecture-7/allslides.html中“谓词语义”部分的以下引用,确实可以预期上面的XPath表达式可以正常工作。因此,也许我想做的事情是不可能的,但我只是想确保自己没有遗漏任何东西。
谓词将表达式值转换为 布尔值...如果节点集为非空,则它为true。
我要使用XPath谓词或等效的XPath表达式来实现什么吗?是否以编程方式确认所有祖先都满足条件的唯一选择?
答案 0 :(得分:1)
您可以使用下面的xpath。
//RootFolder[.//File[not(ancestor::Folder[@visible='false'])]]
这里正在检查根文件夹是否有任何带有visible = false的文件夹,还正在检查该文件夹是否具有文件。
截屏:
答案 1 :(得分:1)
我认为您的初次尝试很接近。我认为您只需要检查没有祖先File
且其Folder
属性设置为visible
的{{1}} ...
false
或者如果您不在意//RootFolder[.//File[not(ancestor::Folder/@visible='false')]]
的值是什么,只要它不是visible
...
true
答案 2 :(得分:1)
在XPath 2.0中,您可以使用
//RootFolder[every $a in ancestor::* satisfies $a/@visible='true']
这可能是最清晰的说法。
如果只有XPath 1.0,则可以将其表示为双重否定形式:
//RootFolder[not(ancestor::*[not(@visible='true')])]
即找到所有没有RootFolder
祖先的@visible='true'
。
顺便说一句,这有助于说明您使用的是哪个XPath版本,因为任何复杂查询的答案都将取决于版本。