HtmlAgilityPack并选择节点和子节点

The*_*ack 40 c# xpath html-agility-pack

希望有人可以帮助我.

假设我有一个包含多个div的html文档,如下例所示:

<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>
Run Code Online (Sandbox Code Playgroud)

我正在使用HtmlAgilityPack来获取html文档.我需要知道的是我如何获得每个"search_hit"-div的跨度?

我的第一个想法是这样的:

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

     }
}
Run Code Online (Sandbox Code Playgroud)

每个div应该是包含spans作为属性的对象.I. e.

public class Record
    {
        public string Name { get; set; }
        public string company { get; set; }
        public string street { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

然后填写此清单:

public List<Record> Results = new List<Record>();
Run Code Online (Sandbox Code Playgroud)

但我正在使用的XPATH并没有在子节点中进行搜索,因为它应该这样做.它接缝一遍又一遍地搜索整个文档.

我的意思是我已经让它以这种方式工作,我只是得到整个页面的跨度.但后来我在跨度和div之间没有任何关系.意思是:我不知道哪个跨度与哪个div有关.

有人知道解决方案吗?我已经玩了很多,我现在完全糊涂了:)

任何帮助表示赞赏!

Ben*_*ela 54

如果您使用//,它将从文档开始搜索.

用于.//从当前节点搜索所有内容

 foreach (HtmlAgilityPack.HtmlNode node2 in node.SelectNodes(".//span[@prop]"))
Run Code Online (Sandbox Code Playgroud)

或者完全删除前缀以搜索直接子项:

 foreach (HtmlAgilityPack.HtmlNode node2 in node.SelectNodes("span[@prop]"))
Run Code Online (Sandbox Code Playgroud)


shr*_*iek 34

以下适用于我.重要的是就像BeniBela注意到在第二次调用'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);
}
Run Code Online (Sandbox Code Playgroud)