我一直在寻找类似的问题并在线搜索,但我似乎无法找到解决方案。我要做的是按顺序选择所有DOM元素(等),然后将它们放入arraylist或其他东西。
目前我有
public void Parse()
{
HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
// There are various options, set as needed
//htmlDoc.OptionFixNestedTags = true;
// filePath is a path to a file containing the html
htmlDoc.Load("Test.html");
// Use: htmlDoc.LoadHtml(xmlString); to load from a string (was htmlDoc.LoadXML(xmlString)
// ParseErrors is an ArrayList containing any errors from the Load statement
if (htmlDoc.ParseErrors != null && htmlDoc.ParseErrors.Count() > 0)
{
Console.WriteLine("There was an error parsing the HTML file");
}
else
{
if (htmlDoc.DocumentNode != null)
{
htmlDoc.DocumentNode.Descendants();
Console.WriteLine("document node not null");
//HtmlAgilityPack.HtmlNode bodyNode = htmlDoc.DocumentNode.SelectSingleNode("//body");
foreach (HtmlNode node in htmlDoc.DocumentNode.Descendants())
{
Console.WriteLine(node.Name);
}
}
}
}
代码输出节点的名称(html,title,image等),但它将结束标记输出为“#text”。我认为这是因为标签以“/”开头如何才能正确读出所有DOM元素?
答案 0 :(得分:1)
我怀疑你看到的#text
元素是换行符而不是结束标记。例如这个html输入:
<div>
<a href="http://example.org"></a>
</div>
使用您的代码将输出:
div
#text <- line break between <div> and <a>
a
#text <- line break between </a> and </div>
您可以使用此XPath查询来获取那些不是纯文本节点的元素(跳过那些不必要的换行符):
foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//*"))
{
Console.WriteLine(node.Name);
}
XPath意味着,选择具有任何名称(*
)的当前元素的所有后代。
答案 1 :(得分:0)
“#text”是文本节点的名称,而结束标记不表示为DOM中的任何唯一标识。
<div><span>foo</span> bar</div>
会给你一棵树
div
span
#text:foo
#text:bar