【问题标题】:XPath find all elements with specific child nodeXPath 查找具有特定子节点的所有元素
【发布时间】:2012-06-04 12:20:12
【问题描述】:

您能帮我找出下面示例中所有具有子元素 c 的元素 b 吗?

<a>
    <b name = "b1"></b>
    <b name = "b2"><c/></b>
    <b name = "b3"></b>
</a>

xpath 查询必须返回 b2 元素

第二个问题是 我想结合 2 个条件:我想获取具有 name = "b2" 并具有元素 c 的元素 但是这种语法似乎不起作用: //b[@name='b2' 和 c]

【问题讨论】:

  • “似乎不起作用”到底是什么意思?请提出一个新的、单独的问题并提供完整的(尽可能小)源 XML 文档、使用的 XPath 表达式以及想要的结果和您得到的实际结果。对于当前的 XML 文档,XPath 表达式 //b[@name='b2' and c] 选择 a 的第二个子项——完全符合它的要求。

标签: xml xpath


【解决方案1】:

只要知道 XML 文档的结构,最好避免使用 // XPath 伪操作符,因为它的使用会导致效率大大降低(遍历整个文档树)。

因此,我为所提供的 XML 文档推荐这个 XPath 表达式:

/*/b[c]

这会选择任何b 元素,它是 XML 文档顶部元素的子元素,并且具有名为 c 的子元素。

更新:OP 在几分钟前问了第二个问题:

第二个问题是我想结合2个条件:我想得到 具有 name = "b2" 并具有元素 c 的元素但这 语法似乎不起作用://b[@name='b2' and c]

提供的 XPath 表达式确实选择了想要的元素。

这是基于 XSLT 的验证

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/*">
     <xsl:copy-of select="//b[@name='b2' and c]"/>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时:

<a>
    <b name = "b1"></b>
    <b name = "b2"><c/></b>
    <b name = "b3"></b>
</a>

计算 XPath 表达式并将正确选择的元素复制到输出:

<b name="b2">
   <c/>
</b>

【讨论】:

  • 我使用 python 来选择元素如果我使用:root.findall("b[c]") 结果是我想要的但是如果我使用 root.findall("b[@name= 'b2' 和 c]") 我有错误“无效谓词”也许我为 Python 打开另一个问题?
  • @HOAINAMNGUYEN:是的,打开另一个问题似乎是正确的做法——这似乎是与 Python 相关的问题。
  • 我知道//some-element-deep-within-the-dom 会搜索every //some-element-deep-within-the-dom,但如果@ 987654331@ 被移动到 dom 内的其他地方???
  • @Anthony,如果 XML 文档发生变化,那么最好修改所有 XPath 表达式。提议的措施并不总是安全和充分的。有一种方法可以编写 XPath 表达式,该表达式将始终选择预期的内容,无论文档中的更改如何——只是不要在表达式中使用任何名称。
  • 我不太明白你的回答。为什么它不安全和足够?是的,我当然会通过 ID 选择元素,但在许多情况下元素没有 ID,所以......无论如何,显然没有万无一失的方法可以始终选择特定元素。例如,即使您不按名称选择元素,如果文档的结构发生变化,那么您的选择器也会中断
【解决方案2】:

应该这么简单

//b[c]

即在任何有c 孩子的地方找到b

【讨论】:

  • 您好,现在我想结合 2 个条件:我想获取具有 name = "b2" 且具有元素 c 的元素 但是这种语法似乎不起作用://b[@name ='b2' 和 c]
  • 为我工作(在 Perl 中使用 xsh)。
猜你喜欢
  • 2011-07-06
  • 2021-07-16
  • 1970-01-01
  • 1970-01-01
  • 2021-06-14
  • 2023-03-26
  • 2014-03-21
  • 1970-01-01
  • 2011-01-30
相关资源
最近更新 更多