Instruction XPath pour trouver le frère précédent le plus proche

c# html-agility-pack xpath

Question

J'utilise HTMLAgilityPack dans une application WPF C # pour parcourir certaines balises d'ancrage dans une page HTML locale et extraire l'attribut href. Cela fonctionne très bien, mais je dois ensuite trouver le titre sous lequel se trouve l'ancre dans le document HTML (qui est également une balise d'ancrage). Cela devrait être assez facile à faire avec XPath, mais je n'arrive pas à obtenir une déclaration qui fonctionne pour tous les scénarios.

Voici un exemple de mon code HTML (sur lequel je n'ai aucun contrôle):

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

Après avoir trouvé link1, je veux ensuite trouver subt1. De même pour link2 et link3. Mais pour link4 et link5, je veux trouver subtitle2. J'utilise cette instruction XPath (la première section est là pour simuler la sélection d'une balise d'ancrage, que j'utilise avec un évaluateur XPath en ligne https://www.freeformatter.com/xpath-tester.html ) :

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

Cela fonctionne pour link1 à link3, mais pour link4 et link5, il renvoie les sous-titres1 et les sous-titres2. L'ajout de [1] à previous-sobling preceding-sibling::t corrige pour link4, mais le casse pour link2, link3 et link5:

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

J'ai aussi essayé d'ajouter last() à preceding-sibling::t , mais il en résulte que rien n'est trouvé pour aucun des liens:

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

Je suis sûr qu'il existe une solution simple, mais je ne suis pas du tout compétent avec XPath, alors je me bats. Comment puis-je obtenir ma déclaration XPath d'origine pour renvoyer le plus proche frère?

Réponse acceptée

localisateur pour obtenir des sous-titres par le texte du lien ('link4')

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

logique:

//a[text()='link4'] - récupère un élément par un texte lié

//a[text()='link4']/preceding::tr - recherche tous les parents tr

[.//a[@class='subtitle']] - [.//a[@class='subtitle']] premier parent contenant la balise a avec la classe' subtitle '

(someLocator)[last()] - (someLocator)[last()] localisateur correspondant, dans notre cas, récupère le dernier parent contenant la balise a avec la classe ' subtitle '

une autre option - rechercher initialement tr place d' a élément

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

Espérons que cela aidera tout le monde à obtenir la logique des localisateurs de bâtiment ob


Réponse populaire

Essayez d'utiliser le xpath:

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

<your_input> pourrait être link1.pdf à link5.pdf



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi