简体   繁体   中英

How to get all input elements in a form with HtmlAgilityPack without getting a null reference error

Example 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>

Test code:

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

The statement doc.GetElementbyId("form2").SelectNodes(".//input") gives me a null reference.

Anything I did wrong? thanks.

You can do the following:

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);
    }
}

By default HTML Agility Pack parses forms as empty node because they are allowed to overlap other HTML elements. The first line, ( HtmlNode.ElementsFlags.Remove("form"); ) disables this behavior allowing you to get the input elements inside the second form.

Update: Example of form elements overlap:

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

The element begins inside a table but is closed outside the table element. This is allowed in the HTML specification and HTML Agility Pack has to deal with it.

只需将它们放入数组中:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM