【发布时间】:2011-07-18 14:30:13
【问题描述】:
我想解析一个 html 页面来获取一些数据。 首先,我使用 SgmlReader 将其转换为 XML 文档。 然后,我将结果加载到 XMLDocument,然后通过 XPath 导航:
//contains html document
var loadedFile = LoadWebPage();
...
Sgml.SgmlReader sgmlReader = new Sgml.SgmlReader();
sgmlReader.DocType = "HTML";
sgmlReader.WhitespaceHandling = WhitespaceHandling.All;
sgmlReader.CaseFolding = Sgml.CaseFolding.ToLower;
sgmlReader.InputStream = new StringReader(loadedFile);
XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;
doc.XmlResolver = null;
doc.Load(sgmlReader);
此代码在大多数情况下都可以正常工作,除了在此站点上 - www.arrow.com(尝试搜索类似 OP295GS 的内容)。我可以使用以下 XPath 获得带有结果的表:
var node = doc.SelectSingleNode(".//*[@id='results-table']");
这给了我一个带有多个子节点的节点:
[0] {Element, Name="thead"}
[1] {Element, Name="tbody"}
[2] {Element, Name="tbody"}
FirstChild {Element, Name="thead"}
好的,让我们尝试使用 XPath 获取一些子节点。但这不起作用:
var childNodes = node.SelectNodes("tbody");
//childnodes.Count = 0
这也是:
var childNode = node.SelectSingleNode("thead");
// childNode = null
甚至这个:
var childNode = doc.SelectSingleNode(".//*[@id='results-table']/thead")
Xpath 查询有什么问题?
我刚刚尝试使用 Html Agility Pack 解析该 HTML 页面,并且我的 XPath 查询运行良好。但是我的应用程序内部使用了 XmlDocument,Html Agility Pack 不适合我。
我什至用 Html Agility Pack 尝试了以下技巧,但 Xpath 查询也不起作用:
//let's parse and convert HTML document using HTML Agility Pack and then load
//the result to XmlDocument
HtmlDocument xmlDocument = new HtmlDocument();
xmlDocument.OptionOutputAsXml = true;
xmlDocument.Load(new StringReader(webPage));
XmlDocument document = new XmlDocument();
document.LoadXml(xmlDocument.DocumentNode.InnerHtml);
也许,网页包含错误(并非所有标签都已关闭等等),但尽管如此,我可以看到子节点(通过 Visual Studio 中的 Quick Watch),但无法通过 XPath 访问它们。
我的 XPath 查询在 Firefox + FirePath + XPather 插件中正常工作,但在 .net XmlDocument 中不工作:(
【问题讨论】:
-
+1 提出一个好问题,并使用 Agility Pack 和 XML 解析器而不是正则表达式解析 HTML。
-
HTML Agility Pack 易于使用,但它有自己的数据类型,在集成现有逻辑时可能会出现问题。
标签: c# .net xml html-parsing