【问题标题】:Xpath expression to find element that do NOT have a matching ancestorXpath 表达式查找没有匹配祖先的元素
【发布时间】:2014-12-09 12:33:52
【问题描述】:

我正在尝试使用 xpath 从页面中提取 HTML5 微数据。我本质上是想说“查找具有 itemprop=name 属性的嵌套节点,这些节点未嵌套在另一个 itemscope 元素中(任何深度)”。鉴于以下示例,我正在尝试查找产品(鞋子)的名称,但我不想要品牌名称(耐克)。

<div itemscope itemtype="http://schema.org/Product>
  <div itemscope itemtype="http://schema.org/Brand">
    <div itemprop="name">Nike</div> <!-- don't want this -->
  </div>
  <div itemprop="name">shoes</div> <!-- do want this -->
</div>

我可以通过使用类似 //*[@itemprop=name] 的方式轻松找到 itemprop=name 元素,但这也会引入品牌名称。顺便说一句,示例中显示的元素可能嵌套在其他标签中,所以我不能简单地说“其直接父级没有 itemscope 属性”我相信可能有一些与我可以使用但我不知道的祖先有关的东西关于xpath的足够了。有什么想法吗?

【问题讨论】:

  • 在这个例子中,shoesitemscope里面,所以澄清一下,你想要的名字最多有一个 @987654325 @祖先,但不是那些拥有多个的?
  • 或者你的意思是对于 any 给定 itemscope 元素 X,提取所有在 X 内但不在任何其他 itemscope 内的名称?
  • 我通过 python 使用 libxml2 (xmlsoft.org)。要回答您最初的问题,实际上在这种情况下,任何一种情况都足够了,但我想总的来说,第二种情况可能更接近。
  • libxml2 仅限于 XPath 1.0,因此“最多一个祖先”方法是您在单个 XPath 中真正可以做到的最好方法。
  • 酷,应该可以。出于兴趣,是否可以使用多个表达式来执行“在 X 内但不在任何其他 itemscope 内的所有名称”?

标签: xpath xpath-1.0


【解决方案1】:

查找所有 itemprop="name" 元素最多具有一个 itemscope 祖先的单个表达式将是

//*[@itemprop = 'name'][not(ancestor::*[@itemscope][2])]

如果您想从一个特定的 itemscope 节点开始并找到专门嵌套在 it 中的名称(而不是嵌套范围),那么这不是您可以在一个 XPath 中执行的操作1.0 表达式。您必须先提取其后代名称

.//*[@itemprop='name']

然后对于其中的每一个,找到其最近的 itemscope 祖先

ancestor::*[@itemscope][1]

并检查(在 python 端)该节点是否与您开始的节点相同。在 XPath 2.0 中,您可以使用

for $me in . return (.//*[@itemprop='name'][ancestor::*[@itemscope][1] is $me])

但 1.0 没有用于绑定变量的 for $x in Y return Z 结构,或用于比较节点身份的 is 运算符。

【讨论】:

  • itemscope 的祖先对吗?这就是我理解你的 xpath 的方式
  • @TobyHobson 是的,抱歉,我已修正错字。
【解决方案2】:

请试一试:

//*[@itemprop = 'name' and not(ancestor::*[@itemscope][2])]

【讨论】:

    猜你喜欢
    • 2010-09-24
    • 2018-05-29
    • 1970-01-01
    • 2019-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多