XPath / HtmlAgilityPack: Comment trouver un élément (a) avec une valeur spécifique pour un attribut (href) et trouver des colonnes de table adjacentes?

c# html html-agility-pack visual-studio xpath

Question

Je suis assez désespéré parce que je ne vois pas comment atteindre ce que j'ai dit dans la question. J'ai déjà lu d'innombrables exemples similaires, mais je n'en ai trouvé aucun qui fonctionne exactement. Donc, disons que j'ai le code suivant:

<table><tr>
<td><a href="url-a">text A</a></td><td><a>id A</a></td><td><a>img A</a></td>
<td><a href="url-b">text B</a></td><td><a>id B</a></td><td><a>img B</a></td>
<td><a href="url-c">text C</a></td><td><a>id C</a></td><td><a>img C</a></td>
</tr></table>

Maintenant, ce que j'ai déjà, c'est une partie de url-a. Je veux essentiellement savoir comment obtenir les identifiants A et img A. J'essaie de "trouver" la ligne avec XPath mais je ne peux pas trouver un moyen de la faire fonctionner. En outre, il est possible que l’information ne soit pas présente du tout. Ceci est mon dernier essai (sérieusement, je bricole avec cela depuis plus de 3 heures maintenant en essayant de nombreuses façons différentes):

if (htmlDoc.DocumentNode.SelectSingleNode(@"/a[contains(@href, 'part-url-a')]") != null)
    string ida = htmlDoc.DocumentNode.SelectSingleNode(@"/a[contains(@href, 'part-url-a')]/following-sibling::a").InnerText;

Eh bien, apparemment, c'est faux, alors je serais très heureux si quelqu'un pouvait m'aider ici. J'apprécierais également si quelqu'un pouvait m'indiquer un site Web qui explique XPath et les notations / syntaxe en détail avec des exemples comme celui-ci. Les livres sont également les bienvenus.

PS: Je sais que je pourrais atteindre mon objectif sans XPath avec Regex ou tout simplement avec un simple StreamReader en C # et en vérifiant si chaque ligne contient ce dont j'ai besoin mais a) elle est trop fragile pour mes besoins car le code risque d'avoir des sauts de ligne abrupts et b) Je veux vraiment rester fidèle à XPath pour tout ce que je fais dans le cadre de ce projet.

Merci d'avance pour votre aide!

Réponse acceptée

Utilisez les expressions XPath suivantes :

   /*/tr/td[a[@href='url-a']]
                /following-sibling::td[1]
                     /a/text()

Lorsqu'il est évalué par rapport au document XML fourni (malformé mais corrigé) :

<table><tr>
<td><a href="url-a">text A</a></td><td><a>id A</a></td><td><a>img A</a></td>
<td><a href="url-b">text B</a></td><td><a>id B</a></td><td><a>img B</a></td>
<td><a href="url-c">text C</a></td><td><a>id C</a></td><td><a>img C</a></td>
</tr></table>

le noeud de texte recherché est sélectionné :

id A

De même, cette expression XPath :

   /*/tr/td[a[@href='url-a']]
                /following-sibling::td[2]
                     /a/text()

lorsqu'il est comparé au même document XML (ci-dessus), sélectionne l'autre nœud de texte recherché :

img A

Vérification basée sur XSLT :

Lorsque cette transformation est appliquée sur le document XML (ci-dessus):

<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:copy-of select=
   "/*/tr/td[a[@href='url-a']]
                /following-sibling::td[1]
                     /a/text()"/>

  <xsl:text>&#10;</xsl:text>
  <xsl:copy-of select=
   "/*/tr/td[a[@href='url-a']]
                /following-sibling::td[2]
                     /a/text()"/>
 </xsl:template>
</xsl:stylesheet>

les résultats souhaités sont produits :

id A
img A

Réponse populaire

Vous avez un code HTML sérieusement cassé avec des balises td fermeture incomparables. Fixez-les s'il vous plaît. C'est juste une image laide de ce balisage.

Cela dit, espérons-le, Html Agility Pack peut gérer toutes les conneries que vous lui lancez, voici donc comment procéder et analyser les pourriels que vous avez et trouver les valeurs id et img du href :

class Program
{
    static void Main()
    {
        var doc = new HtmlDocument();
        doc.Load("test.html");
        var anchor = doc.DocumentNode.SelectSingleNode("//a[contains(@href, 'url-a')]");
        if (anchor != null)
        {
            var id = anchor.ParentNode.SelectSingleNode("following-sibling::td/a");
            if (id != null)
            {
                Console.WriteLine(id.InnerHtml);
                var img = id.ParentNode.SelectSingleNode("following-sibling::td/a");
                if (img != null)
                {
                    Console.WriteLine(img.InnerHtml);
                }
            }
        }
    }
}


Related

Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow