XPath "folgenden Geschwistern vor"

html-agility-pack xpath

Frage

Ich versuche Elemente (a) mit XPath 1.0 (oder möglicherweise mit Regex) auszuwählen, die Geschwister eines bestimmten Elements (b) folgen, aber nur einem anderen b-Element vorausgehen.

<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>

Ich habe versucht, die Probe so realitätsnah wie möglich zu gestalten. Also in diesem Szenario, wenn ich bei Element bin

<b>First</b>

Ich muss auswählen

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

und wenn ich bei bin

<b>Second</b> 

Ich muss auswählen

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

Irgendeine Idee, wie man das erreicht? Vielen Dank!

Akzeptierte Antwort

Erstelle diesen XPath dynamisch:

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

wobei 'xxxx' durch den Text des aktuellen <b> .

Das setzt voraus , dass alle Elemente sind tatsächlich Geschwister. Wenn dies nicht der Fall ist, können Sie versuchen, mit der preceding und der following Achse zu arbeiten, oder Sie schreiben einen spezifischeren XPath, der der Struktur des Dokuments besser ähnelt.

In XSLT können Sie auch verwenden:

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

Beliebte Antwort

Hier ist eine Lösung, die nur ein einziger XPath-Ausdruck ist .

Verwenden der Kaysian-Formel für den Schnittpunkt zweier Knotensätze $ns1 und $ns2 :

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

Wir ersetzen einfach $ns1 durch den Knotensatz von <a> Geschwistern, die dem aktuellen <b> -Knoten folgen, und wir ersetzen $ns2 durch den Knotensatz von <a> Geschwistern, die dem nächsten <b> Knoten vorausgehen.

Hier ist eine vollständige Transformation, die dies verwendet :

<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>

Wenn diese Transformation auf das folgende XML-Dokument angewendet wird :

<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>

Das korrekte Ergebnis wird erzeugt :

   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>



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum