我在解析html中表单的输入标记子项时遇到问题。我可以使用//输入[@type]从根解析它们,但不能作为特定节点的子节点。
以下是一些说明问题的代码:
private const string HTML_CONTENT =
"<html>" +
"<head>" +
"<title>Test Page</title>" +
"<link href='site.css' rel='stylesheet' type='text/css' />" +
"</head>" +
"<body>" +
"<form id='form1' method='post' action='http://www.someplace.com/input'>" +
"<input type='hidden' name='id' value='test' />" +
"<input type='text' name='something' value='something' />" +
"</form>" +
"<a href='http://www.someplace.com'>Someplace</a>" +
"<a href='http://www.someplace.com/other'><img src='http://www.someplace.com/image.jpg' alt='Someplace Image'/></a>" +
"<form id='form2' method='post' action='/something/to/do'>" +
"<input type='text' name='secondForm' value='this should be in the second form' />" +
"</form>" +
"</body>" +
"</html>";
public void Parser_Test()
{
var htmlDoc = new HtmlDocument
{
OptionFixNestedTags = true,
OptionUseIdAttribute = true,
OptionAutoCloseOnEnd = true,
OptionAddDebuggingAttributes = true
};
byte[] byteArray = Encoding.UTF8.GetBytes(HTML_CONTENT);
var stream = new MemoryStream(byteArray);
htmlDoc.Load(stream, Encoding.UTF8, true);
var nodeCollection = htmlDoc.DocumentNode.SelectNodes("//form");
if (nodeCollection != null && nodeCollection.Count > 0)
{
foreach (var form in nodeCollection)
{
var id = form.GetAttributeValue("id", string.Empty);
if (!form.HasChildNodes)
Debug.WriteLine(string.Format("Form {0} has no children", id ) );
var childCollection = form.SelectNodes("input[@type]");
if (childCollection != null && childCollection.Count > 0)
{
Debug.WriteLine("Got some child nodes");
}
else
{
Debug.WriteLine("Unable to find input nodes as children of Form");
}
}
var inputNodes = htmlDoc.DocumentNode.SelectNodes("//input");
if (inputNodes != null && inputNodes.Count > 0)
{
Debug.WriteLine(string.Format("Found {0} input nodes when parsed from root", inputNodes.Count ) );
}
}
else
{
Debug.WriteLine("Found no forms");
}
}
输出的是:
Form form1 has no children
Unable to find input nodes as children of Form
Form form2 has no children
Unable to find input nodes as children of Form
Found 3 input nodes when parsed from root
我期望Form1和Form2都有子节点,输入[@type]将能够为form1找到2个节点,为form2找到1个节点
是否存在我不应该使用的特定配置设置或方法?有什么想法吗?
谢谢,
史蒂夫
答案 0 :(得分:4)
在HtmlAgilityPack网站上查看此讨论主题 - http://htmlagilitypack.codeplex.com/workitem/21782
这就是他们所说的:
这不是一个错误,而是一个功能,可配置。 FORM被视为这样,因为许多HTML页面曾经有重叠的形式,因为这实际上是原始HTML的(强大的)功能。现在存在XML和XHTML,每个人都认为重叠是一个错误,但它不是(在HTML 3.2中)。 检查HtmlNode.cs文件,并修改ElementsFlags集合(或者如果您愿意,可以在运行时执行此操作)
要修改HtmlNode.cs文件,请注释掉以下行 -
ElementsFlags.Add("form", HtmlElementFlag.CanOverlap | HtmlElementFlag.Empty);
答案 1 :(得分:2)
好吧,我现在已经放弃了HtmlAgilityPack。似乎在该库中还有更多工作要做,以使一切正常。为了解决这个问题,我已将代码移到此处使用SGMLReader库:http://developer.mindtouch.com/SgmlReader
使用此库,我的所有单元测试都会正确传递,示例代码按预期工作。