XPath“之前的兄弟姐妹”

发布于 2024-08-22 01:39:40 字数 971 浏览 4 评论 0原文

我正在尝试使用 XPath 1.0(或者可能使用 Regex)选择元素 (a),这些元素位于特定元素 (b) 的同级元素 (b) 后面,但仅位于另一个 b 元素之前。

<img><b>First</b><br>&nbsp;&nbsp;
<img>&nbsp;&nbsp;<a href="/first-href">First Href</a> - 19:30<br>
<img><b>Second</b><br>&nbsp;&nbsp;
<img>&nbsp;&nbsp;<a href="/second-href">Second Href</a> - 19:30<br>
<img>&nbsp;&nbsp;<a href="/third-href">Third Href</a> - 19:30<br>

我试图让样本尽可能接近现实世界。因此,在这种情况下,当我处于元素状态时,

<b>First</b>

我需要选择

<a href="/first-href">First Href</a> 

,而当我处于元素状态时,

<b>Second</b> 

我需要选择

<a href="/second-href">Second Href</a> 
<a href="/third-href">Third Href</a>

知道如何实现这一目标吗?谢谢你!

I'm trying to select elements (a) with XPath 1.0 (or possibly could be with Regex) that are following siblings of particular element (b) but only preceed another b element.

<img><b>First</b><br>  
<img>  <a href="/first-href">First Href</a> - 19:30<br>
<img><b>Second</b><br>  
<img>  <a href="/second-href">Second Href</a> - 19:30<br>
<img>  <a href="/third-href">Third Href</a> - 19:30<br>

I tried to make the sample as close to real world as possible. So in this scenario when I'm at element

<b>First</b>

I need to select

<a href="/first-href">First Href</a> 

and when I'm at

<b>Second</b> 

I need to select

<a href="/second-href">Second Href</a> 
<a href="/third-href">Third Href</a>

Any idea how to achieve that? Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

っ〆星空下的拥抱 2024-08-29 01:39:40

动态创建此 XPath:

following-sibling::a[preceding-sibling::b[1][.='xxxx']]

其中“xxxx”替换为当前 的文本。

这是假设所有元素实际上都是兄弟元素。如果不是,您可以尝试使用 precedingfollowing 轴,或者编写一个更具体的、更类似于文档结构的 XPath。

在 XSLT 中您还可以使用:

following-sibling::a[
  generate-id(preceding-sibling::b[1]) = generate-id(current())
]

Dynamically create this XPath:

following-sibling::a[preceding-sibling::b[1][.='xxxx']]

where 'xxxx' is the replaced with the text of the current <b>.

This is assuming that all the elements actually are siblings. If they are not, you can try to work with the preceding and following axes, or you write a more specific XPath that better resembles document structure.

In XSLT you could also use:

following-sibling::a[
  generate-id(preceding-sibling::b[1]) = generate-id(current())
]
_失温 2024-08-29 01:39:40

这是一个只有单个 XPath 表达式的解决方案

使用两个节点集 $ns1$ns2交集凯斯公式

  $ns1[count(. | $ns2) = count($ns2)]

我们只需将 $ns1 替换为当前 节点之后的 同级节点集,并且我们将 $ns2 替换为 的节点集 兄弟节点位于下一个 节点之前。

这是使用此转换的完整转换

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

  <xsl:template match="/">
   <xsl:apply-templates select="*/b"/>
  </xsl:template>

  <xsl:template match="b">
    At: <xsl:value-of select="."/>

    <xsl:variable name="vNextB" select="following-sibling::b[1]"/>

    <xsl:variable name="vA-sAfterCurrentB" select="following-sibling::a"/>

    <xsl:variable name="vA-sBeforeNextB" select=
    "$vNextB/preceding-sibling::a
    |
     $vA-sAfterCurrentB[not($vNextB)]
    "/>

    <xsl:copy-of select=
     "$vA-sAfterCurrentB
              [count(.| $vA-sBeforeNextB)
              =
               count($vA-sBeforeNextB)
               ]
    "/>
  </xsl:template>
</xsl:stylesheet>

当此转换应用于以下 XML 文档时

<t>
    <img/>
    <b>First</b>
    <br />  
    <img/>  
    <a href="/first-href">First Href</a> - 19:30
    <br />
    <img/>
    <b>Second</b>
    <br />
    <img/>  
    <a href="/second-href">Second Href</a> - 19:30
    <br />
    <img/> 
    <a href="/third-href">Third Href</a> - 19:30
    <br />
</t>

生成正确的结果

   At: First <a href="/first-href">First Href</a>
    At: Second <a href="/second-href">Second Href</a>
<a href="/third-href">Third Href</a>

Here is a solution which is just a single XPath expression.

Using the Kaysian formula for intersection of two nodesets $ns1 and $ns2:

  $ns1[count(. | $ns2) = count($ns2)]

We simply substitute $ns1 with the nodeset of <a> siblings that follow the current <b> node, and we substitute $ns2 with the nodeset of <a> siblings that precede the next <b> node.

Here is a complete transformation that uses this:

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

  <xsl:template match="/">
   <xsl:apply-templates select="*/b"/>
  </xsl:template>

  <xsl:template match="b">
    At: <xsl:value-of select="."/>

    <xsl:variable name="vNextB" select="following-sibling::b[1]"/>

    <xsl:variable name="vA-sAfterCurrentB" select="following-sibling::a"/>

    <xsl:variable name="vA-sBeforeNextB" select=
    "$vNextB/preceding-sibling::a
    |
     $vA-sAfterCurrentB[not($vNextB)]
    "/>

    <xsl:copy-of select=
     "$vA-sAfterCurrentB
              [count(.| $vA-sBeforeNextB)
              =
               count($vA-sBeforeNextB)
               ]
    "/>
  </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the following XML document:

<t>
    <img/>
    <b>First</b>
    <br />  
    <img/>  
    <a href="/first-href">First Href</a> - 19:30
    <br />
    <img/>
    <b>Second</b>
    <br />
    <img/>  
    <a href="/second-href">Second Href</a> - 19:30
    <br />
    <img/> 
    <a href="/third-href">Third Href</a> - 19:30
    <br />
</t>

the correct result is produced:

   At: First <a href="/first-href">First Href</a>
    At: Second <a href="/second-href">Second Href</a>
<a href="/third-href">Third Href</a>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文