这个想法与the one asked about in this question以及其他许多想法非常相似。
但是,我对提取的整个节点感兴趣,而不是提取孩子。也就是说,常见的解决方案是使用
//node/*[not(self::a)]
代替
//node/*
我正在寻找一种方法来应用相同的逻辑,即排除某个命名分支,而是从更高级别提取节点://node
而不是//node/*
。
对此合适的语法是什么? //node[not(//node/a)]
和类似方法似乎无效。
示例:
<root>
<some_wrapper>
<node>
<a>
<report key=1>
<text>t</text>
</report>
<report key=2>
<text>t</text>
</report>
</a>
<b>
<text>sample_text</text>
<value>1</value>
</b>
<c>
<text>sample_text</text>
<value>2</value>
</c>
</node>
</some_wrapper>
</root>
目标是找到并选择整个node
部分,就像使用//node
时一样,只是选择中不应包括a
个孩子。
//node/*[not(self::a)]
不起作用,因为它选择了节点中的子节点列表,而不是整个节点(如果我正确使用了术语)。
答案 0 :(得分:2)
XPath始终选择输入文档中存在的节点,而不更改。如果要选择一个名为N的节点,则// N将选择该节点;实际上,它返回对源文档中节点的引用。如果该节点在源文档中有子节点,则选择它不会删除那些子节点。
请注意,XPath表达式实际上并未选择子项。许多使用XPath的工具和应用程序通过序列化那些节点的整个XML子树来显示由XPath表达式选择的节点,但这是调用应用程序的决定(它同样可以将结果显示为包含该节点祖先的路径,例如/root[1]/someWrapper[1]/node[2]
。)
如果要创建部分源文档的修改后的副本,则需要XSLT或XQuery,而不是XPath。
答案 1 :(得分:1)
这里是xpath,用于获取a
下的所有节点(some_wrapper
除外)。
//some_wrapper/descendant::*[not(name()='a' or ancestor::a)]
如果您只想过滤node
标签下的项目,请使用以下内容。
//some_wrapper/descendant::*[not(name()='a' or ancestor::a) and (name()='node' or ancestor::node)]