如何使用HtmlAgilityPack获取表单中的所有输入元素而不出现空引用错误

24

示例HTML:

 <html><body>
     <form id="form1">
       <input name="foo1" value="bar1" />
       <!-- Other elements -->
     </form>
     <form id="form2">
       <input name="foo2" value="bar2" />
       <!-- Other elements -->
     </form>   
 </body></html>

测试代码:

HtmlDocument doc = new HtmlDocument();
doc.Load(@"D:\test.html");
foreach (HtmlNode node in doc.GetElementbyId("form2").SelectNodes(".//input"))
{
    Console.WriteLine(node.Attributes["value"].Value);            
}

这个语句 doc.GetElementbyId("form2").SelectNodes(".//input") 返回了 null 引用。

我有做错什么吗?谢谢。

2个回答

45

您可以执行以下操作:

HtmlNode.ElementsFlags.Remove("form");

HtmlDocument doc = new HtmlDocument();

doc.Load(@"D:\test.html");

HtmlNode secondForm = doc.GetElementbyId("form2");

foreach (HtmlNode node in secondForm.Elements("input"))
{
    HtmlAttribute valueAttribute = node.Attributes["value"];

    if (valueAttribute != null)
    {
        Console.WriteLine(valueAttribute.Value);
    }
}

默认情况下,HTML Agility Pack解析表单时会将其解析为空节点,因为它们可以重叠其他HTML元素。第一行代码(HtmlNode.ElementsFlags.Remove("form");)禁用了此行为,使您能够获取第二个表单内的输入元素。

更新: 表单元素重叠的示例:

<table>
<form>
<!-- Other elements -->
</table>
</form>

这个元素开始于表格内,但在表格元素外被关闭。虽然这在HTML规范中是允许的,但HTML Agility Pack必须处理它。


这是否意味着,除非您使用 HtmlNode.ElementsFlags.Remove("form");,否则无法通过HAP解析form元素的子元素? - Kevin Meredith
@Kevin,我不知道其他的替代方案。 - João Angelo
1
5年后——仍然是一个要求,仍然是正确答案。同时,应该在包本身中进行更改... - getglad
应该使用secondForm.SelectNodes(".//input"))而不是secondForm.Elements("input")),否则它将无法获取嵌套的输入元素。 - Stefan Steiger

0

将它们放入数组中:

HtmlNodeCollection resultCollection = doc.DocumentNode.SelectNodes("//*[@type='text']");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接