XPath“;“之前跟随兄弟姐妹”;

XPath“;“之前跟随兄弟姐妹”;,xpath,html-agility-pack,Xpath,Html Agility Pack,我试图选择XPath 1.0中的元素(a)(或者可能是正则表达式中的元素),这些元素跟随特定元素(b)的兄弟元素,但只在另一个b元素之前 <img><b>First</b><br>&nbsp;&nbsp; <img>&nbsp;&nbsp;<a href="/first-href">First Href</a> - 19:30<br> <img><b&

我试图选择XPath 1.0中的元素(a)(或者可能是正则表达式中的元素),这些元素跟随特定元素(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>
首先
-19:30
第二个
-19:30
-19:30
我试图使样品尽可能接近真实世界。所以在这个场景中,当我在元素

<b>First</b>
首先
我需要选择

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

当我在

<b>Second</b> 
我需要选择

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


你知道怎么做到吗?谢谢大家!

动态创建此XPath:

following-sibling::a[preceding-sibling::b[1][.='xxxx']]
其中“xxxx”被替换为当前
的文本

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

在XSLT中,您还可以使用:

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

这里是一个解决方案,它只是一个XPath表达式

使用两个节点集
$ns1
$ns2
的交点的Kaysian公式:

  $ns1[count(. | $ns2) = count($ns2)]
我们只需将
$ns1
替换为
-19:30的节点集

第二
  ; - 19:30
 ; - 19:30
生成正确的结果

<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>
<t>
    <img/>
    <b>First</b>
    <br />&#xA0;&#xA0;
    <img/>&#xA0;&#xA0;
    <a href="/first-href">First Href</a> - 19:30
    <br />
    <img/>
    <b>Second</b>
    <br />
    <img/>&#xA0;&#xA0;
    <a href="/second-href">Second Href</a> - 19:30
    <br />
    <img/>&#xA0;
    <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>
At:首先
时间:秒

我们能否假设xml格式良好,即
br
元素实际上是

?还有,
img
元素有内容并以
/>
结尾吗?如果“真实世界”包含格式良好的XML(如果不是的话),那么XPath就不是一个选项,这确实会有所帮助。我希望它是:(然而,我正在使用Html Agility Pack(.NET)来处理标记,如果有帮助的话,它可以容忍格式错误的文档。没有理由假设“真实世界”表示格式不正确的xml。有很多html和格式良好的xml交付的示例。当然,如果您在问题中提到敏捷性,它会使场景更清晰。添加了适当的标记。对单个XPath表达式解决方案感兴趣吗?:)