XPath获取除一个孩子外的完整节点

时间:2019-05-09 13:51:30

标签: xml xpath element

这个想法与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)]不起作用,因为它选择了节点中的子节点列表,而不是整个节点(如果我正确使用了术语)。

2 个答案:

答案 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)]