HtmlAgilityPack et sélection de nœuds et sous-nœuds

c# html-agility-pack xpath

Question

J'espère que quelqu'un peut m'aider.

Disons que j'ai un document HTML qui contient plusieurs divs comme cet exemple:

<div class="search_hit">

    <span prop="name">Richard Winchester</span>
    <span prop="company">Kodak</span>
    <span prop="street">Arlington Road 1</span>

</div>
<div class="search_hit">

    <span prop="name">Ted Mosby</span>
    <span prop="company">HP</span>
    <span prop="street">Arlington Road 2</span>

</div>

J'utilise HtmlAgilityPack pour obtenir le document HTML. Ce que j'ai besoin de savoir, c'est comment puis-je obtenir les étendues pour chaque "search_hit" -div?

Ma première pensée était quelque chose comme ça:

foreach (HtmlAgilityPack.HtmlNode node in doc.DocumentNode.SelectNodes("//div[@class='search_hit']"))
{
     foreach (HtmlAgilityPack.HtmlNode node2 in node.SelectNodes("//span[@prop]"))
     {

     }
}

Chaque div doit être un objet avec les étendues incluses en tant que propriétés. C'est à dire.

public class Record
    {
        public string Name { get; set; }
        public string company { get; set; }
        public string street { get; set; }
    }

Et cette liste sera remplie alors:

public List<Record> Results = new List<Record>();

Mais le XPATH que je suis en train d’utiliser ne fait pas de recherche dans le sous-noeud comme il se doit. Il semble qu'il cherche dans le document entier encore et encore.

Je veux dire, je l’ai déjà fait de cette manière, je n’obtiens que la longueur de la page. Mais alors je n'ai aucune relation entre les étendues et les divs. Cela signifie: je ne sais plus quelle étendue est liée à quelle div.

Est-ce que quelqu'un connaît une solution? J'ai déjà beaucoup joué à ça, je suis totalement confus maintenant :)

Toute aide est appréciée!

Réponse acceptée

Ce qui suit fonctionne pour moi. Le bit important est juste comme BeniBela a noté d'ajouter un point dans le deuxième appel à 'SelectNodes'.

List<Record> lstRecords=new List<Record>();
foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//div[@class='search_hit']"))
{
  Record record=new Record();
  foreach (HtmlNode node2 in node.SelectNodes(".//span[@prop]"))
  {
    string attributeValue = node2.GetAttributeValue("prop", "");
    if (attributeValue == "name")
    {
      record.Name = node2.InnerText;
    }
    else if (attributeValue == "company")
    {
      record.company = node2.InnerText;
    }
    else if (attributeValue == "street")
    {
      record.street = node2.InnerText;
    }
  }
  lstRecords.Add(record);
}

Réponse populaire

Si vous utilisez // , la recherche à partir du document commence.

Utilisez .// pour tout rechercher à partir du nœud actuel

 foreach (HtmlAgilityPack.HtmlNode node2 in node.SelectNodes(".//span[@prop]"))

Ou supprimez entièrement le préfixe pour rechercher uniquement les enfants directs:

 foreach (HtmlAgilityPack.HtmlNode node2 in node.SelectNodes("span[@prop]"))


Related

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