使用Html Agility将元素组合在一起

时间:2011-08-29 20:53:07

标签: c# asp.net html-parsing

我正在尝试使用HTML Agility将HTML文档分组并基于标题标记进行分组 这是原始HTML的样子

<h3>Header 1</h3>
<p>Text...</p>
<p>More Text...</p>
<h3Header 2</h3>
<p>Text...</p>
<p>More Text...</p>
<p>Even more Text...</p>
<h3>Header 3</h3>
<p>Some Text...</p>

我希望在我分组之后让它结束这样的事情

<div id="header_1">
  <h3>Header 1</h3>
  <p>Text...</p>
  <p>More Text...</p>
</div>

<div id="header_2">
  <h3Header 2</h3>
  <p>Text...</p>
  <p>More Text...</p>
  <p>Even more Text...</p>
</div>

<div id="header_3">
  <h3>Header 3</h3>
  <p>Some Text...</p>
</div>

或者像这样

<h3>Header 1</h3>
<div id="header_1">
  <h3>Header 1</h3>
  <p>Text...</p>
  <p>More Text...</p>
</div>


<h3Header 2</h3>
<div id="header_2">
  <p>Text...</p>
  <p>More Text...</p>
  <p>Even more Text...</p>
</div>

<h3>Header 3</h3>
<div id="header_3">
  <p>Some Text...</p>
</div>

HTML Agility很棒,但如果有人知道另一种方法来实现这一点,那就太棒了!

1 个答案:

答案 0 :(得分:1)

使用AgilityPack可以轻松完成。首先,您需要获取所有顶级<h3>,在每个<div>之前(或之后)创建<h3>,然后迭代当前<h3>的以下兄弟,直到找到下一个<h3>或兄弟姐妹的结尾,最后将这些节点移动到新创建的<div>

var h3s = doc.DocumentNode.SelectNodes("h3");
var idx = 1;
foreach (var h3 in h3s)
{
    var div = HtmlNode.CreateNode(string.Format("<div id='header_{0}'></div>", idx++));
    h3.ParentNode.InsertBefore(div, h3);
    var group = new List<HtmlNode> { h3 };

    for (var next = h3.NextSibling; next != null && next.Name != "h3"; next = next.NextSibling)
        group.Add(next);

    foreach (var item in group)
    {
        item.Remove();
        div.AppendChild(item);
    }
}

这会让你感觉像是(我从你的来源更正了<h3Header 2</h3>):

<div id='header_1'>
  <h3>Header 1</h3>
  <p>Text...</p>
  <p>More Text...</p>
</div>
<div id='header_2'>
  <h3>Header 2</h3>
  <p>Text...</p>
  <p>More Text...</p>
  <p>Even more Text...</p>
</div>
<div id='header_3'>
  <h3>Header 3</h3>
  <p>Some Text...</p>
</div>