【发布时间】:2011-05-07 12:45:03
【问题描述】:
Traverse() 中有一个错误导致它多次迭代节点。
错误代码
public IEnumerable<HtmlNode> Traverse()
{
foreach (var node in _context)
{
yield return node;
foreach (var child in Children().Traverse())
yield return child;
}
}
public SharpQuery Children()
{
return new SharpQuery(_context.SelectMany(n => n.ChildNodes).Where(n => n.NodeType == HtmlNodeType.Element), this);
}
public SharpQuery(IEnumerable<HtmlNode> nodes, SharpQuery previous = null)
{
if (nodes == null) throw new ArgumentNullException("nodes");
_previous = previous;
_context = new List<HtmlNode>(nodes);
}
测试代码
static void Main(string[] args)
{
var sq = new SharpQuery(@"
<a>
<b>
<c/>
<d/>
<e/>
<f>
<g/>
<h/>
<i/>
</f>
</b>
</a>");
var nodes = sq.Traverse();
Console.WriteLine("{0} nodes: {1}", nodes.Count(), string.Join(",", nodes.Select(n => n.Name)));
Console.ReadLine();
输出
19 个节点:#document,a,b,c,g,h,i,d,g,h,i,e,g,h,i,f,g,h,i
预期输出
每个字母 a-i 打印一次。
似乎无法弄清楚哪里出了问题...node.ChildNodes 是否只返回直接孩子,对吗? (来自 HtmlAgilityPack)
如果你想尝试自己运行的话,完整的课程(浓缩)。
public class SQLite
{
private readonly List<HtmlNode> _context = new List<HtmlNode>();
private readonly SQLite _previous = null;
public SQLite(string html)
{
var doc = new HtmlDocument();
doc.LoadHtml(html);
_context.Add(doc.DocumentNode);
}
public SQLite(IEnumerable<HtmlNode> nodes, SQLite previous = null)
{
if (nodes == null) throw new ArgumentNullException("nodes");
_previous = previous;
_context = new List<HtmlNode>(nodes);
}
public IEnumerable<HtmlNode> Traverse()
{
foreach (var node in _context)
{
yield return node;
foreach (var child in Children().Traverse())
yield return child;
}
}
public SQLite Children()
{
return new SQLite(_context.SelectMany(n => n.ChildNodes).Where(n => n.NodeType == HtmlNodeType.Element), this);
}
}
【问题讨论】:
-
调试器告诉你什么?
-
@Oli:关于什么?我应该在哪里设置断点?这是一个逻辑错误,而不是崩溃错误。
-
@Mark:我不确定我是否理解。调试器不仅仅用于诊断崩溃!
-
你能发布整个 SharpQuery 类吗?
-
@BFree:675 行,不到四分之一完整>。
标签: c# html-agility-pack