Html敏捷性xpath得到以下节点if

时间:2016-08-10 11:27:01

标签: c# xpath html-agility-pack

我有一个html文档,结构如下:

<h3><a name="sect55">55</a></h3>
<p></p>
<p class="choice"><a href="#sect325"></a></p>

<h3><a name="sect56"></a></h3>
<p></p>
<p class="choice"><a href="#sect222"></a></p>

<h3><a name="sect57"></a></h3>
<p></p>
<p class="choice"><a href="#sect164"></a></p>
<p class="choice"><a href="#sect109"></a></p>
<p class="choice"><a href="#sect308"></a></p>

我想在单独的List中检索所有节点,直到下一节,直到下一个<h3>

现在我正在使用:

for (int paragraph = xx; paragraph <= yy; paragraph++)
{
       nameActual = "sect" + paragraph;
       nameNext = "sect" + (paragraph + 1);
       HtmlNodeCollection NodeOfParagraph = doc.DocumentNode.SelectNodes(String.Format("//h3[a[@name='{0}']]/following-sibling::p[following::h3/a[@name='{1}']]", nameActual, nameNext));

      //Multiples actions on my NodeOfParagraph
}

所以我选择了第一个<h3>,它拥有我正在寻找的值的<a>,然后我选择所有<p>个拥有以下节点<a>的节点{1}}我的下一个价值。

它可以工作,但需要很长时间,我想因为每个节点都会测试所有其他节点的值。

如何改善查询效果?

1 个答案:

答案 0 :(得分:1)

您可以执行以下操作:

  1. 查找所有部分定义并将其存储在列表中
  2. 循环显示部分定义
    • 通过指定查询中下一部分的确切名称,获取此部分与下一部分之间的所有节点(如果没有更多部分定义,则获取文档的结尾)
  3. var doc = new HtmlDocument();
    doc.Load(@"path\to\file.html");
    var sects = doc.DocumentNode.SelectNodes("//h3[a[starts-with(@name, 'sect')]]");
    
    for (var index = 0; index < sects.Count; index ++)
    {
        var isLast = (index == sects.Count - 1);
        var xpath = ".//following-sibling::p";
        if (!isLast)
            xpath += string.Format("[following-sibling::h3[1][a/@name = '{0}']]", sects[index + 1].SelectSingleNode("./a").Attributes["name"].Value);
        var collection = sects[index].SelectNodes(xpath);
    
    }
    

    这将具有以下优势:

    • 没有尝试查找不存在的区号
    • 使用上下文节点(以./开始查询),以便不搜索文档中不必要的部分
    • 停在下一个h3h3[1]),以便不搜索文档中不必要的部分
    • 仅搜索兄弟姐妹而非后代(following-sibling::而不是following::