XPath-Anweisung, um das nächste vorausgehende Geschwister zu finden

c# html-agility-pack xpath

Frage

Ich verwende das HTMLAgilityPack in einer C # -WPF-Anwendung, um einige Anchor-Tags in einer lokalen HTML-Seite zu durchlaufen und das href-Attribut zu extrahieren. Das funktioniert großartig, aber ich muss dann den Titel finden, in dem sich der Anker innerhalb des HTML-Dokuments befindet (was auch ein Anker-Tag ist). Dies sollte mit XPath einfach sein, aber ich kann einfach nicht eine Anweisung erhalten, die für alle Szenarien funktioniert.

Hier ist ein Beispiel meines HTML (auf das ich keine Kontrolle habe):

<html>
    <body>
        <table>
            <tr>
                <td><div><a href="#maintitle" class="title">maintitle</a></div></td>
            </tr>
            <tr>
                <td><div><a href="#subtitle1" class="subtitle">subtitle1</a></div></td>
            </tr>
            <tr>
                <td><div><a href="link1.pdf">link1</a></div></td>
            </tr>
            <tr>
                <td><div><a href="link2.pdf">link2</a></div></td>
            </tr>
            <tr>
                <td><div><a href="link3.pdf">link3</a></div></td>
            </tr>
            <tr>
                <td><div><a href="#subtitle2" class="subtitle">subtitle2</a></div></td>
            </tr>
            <tr>
                <td><div><a href="link4.pdf">link4</a></div></td>
            </tr>
            <tr>
                <td><div><a href="link5.pdf">link5</a></div></td>
            </tr>
        </table>
    </body>
</html>

Nachdem ich link1 gefunden habe, möchte ich dann Untertitel1 finden. Ebenso für link2 und link3. Aber für link4 und link5 möchte ich Untertitel2 finden. Ich verwende diese XPath-Anweisung (der erste Abschnitt dient nur dazu, die Auswahl eines Anchor-Tags zu simulieren, das ich mit einem Online-XPath-Evaluator verwendet habe https://www.freeformatter.com/xpath-tester.html ) :

//a[@href='link4.pdf']/ancestor::tr/preceding-sibling::tr//a[@class='subtitle']

Dies funktioniert für link1 zu link3, aber für link4 und link5 gibt es sowohl Untertitel1 als auch Untertitel2 zurück. Hinzufügen von [1] zu preceding-sibling::t behebt es für link4, aber bricht es für link2, link3 und link5:

//a[@href='link4.pdf']/ancestor::tr/preceding-sibling::tr[1]//a[@class='subtitle']

Ich habe auch versucht, last() zu preceding-sibling::t hinzuzufügen, aber dies führt dazu, dass nichts für einen der Links gefunden wird:

//a[@href='link4.pdf']/ancestor::tr/preceding-sibling::tr[last()]//a[@class='subtitle']

Ich bin mir sicher, dass es eine einfache Lösung gibt, aber mit XPath bin ich nicht kompetent, also kämpfe ich. Wie bekomme ich meine ursprüngliche XPath-Anweisung, um das nächste Geschwister zurückzugeben?

Akzeptierte Antwort

Locator, um Untertitel nach Linktext zu erhalten ('link4')

(//a[text()='link5']/preceding::tr[.//a[@class='subtitle']])[last()]

Logik:

//a[text()='link4'] - Element durch verknüpften Text erhalten

//a[text()='link4']/preceding::tr - Suche nach allen tr Eltern

[.//a[@class='subtitle']] - [.//a[@class='subtitle']] erste Elternteil mit dem Tag a mit dem subtitle Klasse

(someLocator)[last()] - (someLocator)[last()] sich den letzten passenden Element-Locator, in unserem Fall - holen Sie sich das letzte Elternteil mit dem Tag a mit dem subtitle Klasse

eine andere Option - zunächst Suche tr anstelle a Elements

(//tr[.//a[text()='link5']]/preceding-sibling::tr//a[contains(@class,'subtitle')])[last()]

hoffentlich wird es jedem helfen, die logischen ob Gebäude Locators zu bekommen


Beliebte Antwort

Probieren Sie den xpath:

//a[@href='<your_input>']/preceding-sibling::tr[.//a[@class='subtitle']][1]

wo <your_input> könnte link1.pdf zu link5.pdf



Related

Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow