HtmlAgilityPack und Auswählen von Knoten und Unterknoten

c# html-agility-pack xpath

Frage

Hoffe jemand kann mir helfen.

Nehmen wir an, ich habe ein HTML-Dokument, das mehrere Divs wie dieses Beispiel enthält:

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

Ich verwende HtmlAgilityPack, um das HTML-Dokument zu erhalten. Was ich wissen muss ist, wie kann ich die Spannen für jedes "search_hit" -div bekommen?

Mein erster Gedanke war in etwa so:

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

     }
}

Jedes div sollte ein Objekt mit den eingeschlossenen Spannen als Eigenschaften sein. I. e.

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

Und diese Liste soll dann gefüllt werden:

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

Aber das XPATH, das ich benutze, sucht nicht im Unterknoten, wie es sollte. Es scheint, dass es das gesamte Dokument immer wieder durchsucht.

Ich meine, ich habe es schon so funktioniert, dass ich nur die Spannweite der ganzen Seite bekomme. Aber dann habe ich keine Beziehung zwischen den Spannen und divs. Bedeutet: Ich weiß nicht mehr welche Spanne zu welcher div.

Kennt jemand eine Lösung? Ich habe schon so viel gespielt, dass ich jetzt total verwirrt bin :)

Jede Hilfe wird geschätzt!

Akzeptierte Antwort

Das Folgende funktioniert für mich. Das wichtige Bit ist genau wie BeniBela notierte, um einen Punkt im zweiten Aufruf zu 'SelectNodes' hinzuzufügen.

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);
}

Beliebte Antwort

Wenn Sie // , wird vom Anfang des Dokuments aus gesucht.

Verwenden Sie .// , um alle vom aktuellen Knoten aus zu suchen

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

Oder löschen Sie das Präfix vollständig, um nur nach direkten Kindern zu suchen:

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


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