【问题标题】:XPath to match only directly following siblingsXPath 仅匹配直接跟随的兄弟姐妹
【发布时间】:2010-01-06 21:23:46
【问题描述】:

我有以下类型的 HTML。内容按<div "id=foo"><div "id=foo1"> 元素分组,<div "style=padding…"> 介于两者之间。

我正在尝试弄清楚如何制作一个 XPath 表达式,该表达式将允许我触发 "id=foo" 以返回兄弟 <div>s 和 "style=padding…"

获取<div id="foo"> 很简单。但是,我不能只基于"style=padding…" 做一个following-sibling,因为它会返回所有匹配的<div>s。

我需要一种方法来返回匹配的<div>s,直到我找到与"id=foo1" 匹配的兄弟姐妹。我很确定我缺少一种简单的方法!

<div id="foo">stuff...</div>

<div style="padding:2px; ">stuff...</div>

<div id="foo1">stuff...</div>

<div id="foo">stuff...</div>

<div style="padding:2px; ">stuff...</div>
<div style="padding:2px; ">stuff...</div>
<div style="padding:2px; ">stuff...</div>

<div id="foo1">stuff...</div>

【问题讨论】:

  • 您应该能够构造一个基于“preceding-sibling”轴的谓词,并将其应用于使用“following-sibling”轴检索的节点集。但是,我不想尝试调试/维护该查询。
  • 如果你在谈论xhtml,是否有多个元素具有相同的id? (id="foo")。

标签: xpath


【解决方案1】:

有什么原因你不能采取简单的方法来挑选所有没有 id 属性的divs?

div[not(@id)]

或者,也许,divs 带有样式属性?

div[@style]

如果出于某种原因,这不可接受,您可以使用更符合您的想法的方法:

div[@style][following-sibling::div[@id='foo1']]

获取所有divs 的样式属性,这些属性在divs 之前匹配特定的id。这是你要求的吗?

我想您的实际输入 HTML 没有您提供的示例那么简单,但是我列出的所有这些 XPath 表达式都适用于您的示例。如果您能提供更具体的详细信息,说明您的预期输出是什么以及您遇到的问题,那么我可以为您提供更多帮助。

【讨论】:

    【解决方案2】:

    一种看起来不太好看的方式来做您似乎打算做的事情如下(请注意,这是基于您真的拥有多个 &lt;div&gt;s 和相同的 @987654322 的假设@!):

    /*/div[@id='foo'][n]/following-sibling::div[@style='padding…']
    [
      count(preceding-sibling::div[@id='foo']) 
      =
      count(/*/div[@id='foo'][n]/preceding-sibling::div[@id='foo']) + 1
    ]
    

    XPath 表达式的第一行采用任何 &lt;div style="padding…"&gt;,它是第 n 个 &lt;div id="foo"&gt; 的后续兄弟(这是你自己得到的,选择 all他们)。

    然后,它会为它们中的每一个计算前面的兄弟&lt;div id="foo"&gt;,并仅匹配此处具有正确数字的那些,例如&lt;div id="foo"&gt; 比相应的 &lt;div id="foo"&gt; 本身 多一个。改变数字 n 以选择另一组。

    如果你的输入确实有,事实上,没有有多个具有相同 id 的元素,它会变得简单得多:

    //div[@style='padding…'][preceding-sibling::div[@id][1]/@id = 'foo']
    

    这会选择那些&lt;div style="padding…"&gt;,其中第一个前面的&lt;div&gt;(有一个id)的id值为'foo'。如前所述,这意味着只有一个&lt;div&gt; 的ID 为'foo',并且&lt;div&gt;s 之前的other 确实没有 有一个ID。

    【讨论】:

      【解决方案3】:

      我认为使用 XPath 查询这是不可行的。它需要您记住所选 div 的索引(不是那么难),然后将其兄弟姐妹的索引与那个索引以及它后面的第一个 #foo1 div 进行比较。如果可能的话,这是一个非常复杂的 XPath 查询。 XPath 不容易让您保留多个范围来比较元素或属性。

      您最好先选择两个分隔符 div,然后匹配中间的那些。这在代码中比在 XPath 中要容易得多。

      如果您真的需要在 XPath 中执行此操作,您希望分隔符 div 具有不同的 id(首先,具有相同 id 的多个元素无论如何都是无效的,因此请使用不同的或类名),然后以某种方式将 div 上的 id 或类名与填充匹配。换句话说,更改 HTML 以提供足够的参考,而不是尝试完全在 XPath 中解决。

      【讨论】:

        【解决方案4】:

        您最好的长期选择是修复 HTML。任何其他解决方案都是脆弱的。

        【讨论】:

          【解决方案5】:

          给他们一个类名而不是使用内联样式

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-10-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多