HtmlAgilityPack在c#中同时获取两个节点

时间:2016-03-03 13:12:01

标签: c# xpath html-agility-pack

我正在尝试解析一个html页面, 我会从这段代码中得到一对节点

 <li class="classli"> 
    <div class="element">element1</div>  
    <div class="description">description1</div> 
  </li>  
  <li class="classli"> 
    <div class="element">element2</div>  
    <div class="description">description2</div> 
  </li>  
  <li class="classli"> 
    <div class="xxxelementclass">element3</div>  
    <div class="description">description3</div> 
  </li>  
  <li class="classli"> 
    <div class="element">element4</div>  
    <div class="xxxclass">description4</div> 
  </li> 

我在c#中试过这个:

foreach(var node in doc.SelectNodes("//li[contains(@class,classli)]"))
{
    listelement.add(node.SelectSingleNode("//div[contains(@class,element)]").InnerText);
    listdescription(node.SelectSingleNode("//div[contains(@class,description)]").InnerText);
}
HTML页面中的

,并非所有(li)标签都包含相同的子标签,I 会得到描述和元素只有两个存在

3 个答案:

答案 0 :(得分:1)

让你的每个xpath看起来像下面的

//li[contains(@class,'classli') and ./div[contains(@class,'element')] and ./div[contains(@class,'description')]]

这只会考虑具有给定类的两个div作为子节点的元素,还要注意每个内部的xpath需要从li节点开始查找后代节点,因此需要使用{{ 1}}适用于儿童,./适用于后代,例如

.//

答案 1 :(得分:1)

通过CSS类匹配的正确XPath表达式有点复杂。采用温和的方法,即this other answer中发布的第二个代码片段,您的任务的XPath将如下(格式化为行以便于阅读):

var query = @"//li[contains(concat(' ', @class, ' '), ' classli ')]
                  [div[contains(concat(' ', @class, ' '), ' element ')]]
                  [div[contains(concat(' ', @class, ' '), ' description ')]]";

foreach(var node in doc.SelectNodes(query))
{
    var elementQuery = "div[contains(concat(' ', @class, ' '), ' element ')]";
    listelement.add(node.SelectSingleNode(elementQuery).InnerText);

    var descriptionQuery = "div[contains(concat(' ', @class, ' '), ' description ')]";
    listdescription.add(node.SelectSingleNode(descriptionQuery).InnerText);
}

答案 2 :(得分:0)

AsEnumerable感谢大家的帮助 我这样解决了

    foreach(var node in doc.SelectNodes("//li[contains(@class,classli)]"))
    {

   List<HTMLNODE> Child = node.childnodes.where(o=> (o.getattribbutevalue(class,"") == "element") or (o.getattribbutevalue(class,"") == "description")).AsEnumerable().ToList();

    }

For(int i = 0; i <= Child.count-1;i=i+2)
{
listelement.add(Child[i].InnerHtml;
listdescription.add(Child[i+1].InnerHtml;
}