0

I'm getting a nullreferenceexception using the htmlagilitypack when my search returns nothing. I need to know how to handle this in code. I'm trying to use ?? but I'm both not using it right and not really sure how to use it anyway. I really just want to know how to run some method if nodes is empty. I could probably just check with an IF if there's no better way.

public DataTable tableIntoTable(HtmlDocument doc)
    {
        var table = new DataTable("MyTable");
        table.Columns.Add("raw", typeof(string));
        var xpath = @"//th[@class='ddlabel'] | //table[not(.//*[contains(@*,'pldefault') or contains(@*,'ntdefault') or contains(@*,'bgtabon')])]";
        var nodes = doc.DocumentNode.SelectNodes(xpath);
        foreach (var node in nodes ?? new HtmlAgilityPack.HtmlNodeCollection {null})
        //new is underlined in red, not sure how it's supposed to work
        {
            table.Rows.Add(node.InnerHtml);
        }


        return table;
    }
Jrow
  • 1,026
  • 2
  • 12
  • 31
  • possible duplicate of [What is a NullReferenceException and how do I fix it?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Jehof May 21 '15 at 11:45
  • why you are not trying only this `foreach (var node in nodes) //new is underlined in red, not sure how it's supposed to work { table.Rows.Add(node.InnerHtml); }` – Mirza Danish Baig May 21 '15 at 11:48

5 Answers5

1

Well, if the exception is caused by nodes being null, then don't try to iterate through it if it is null.

public DataTable tableIntoTable(HtmlDocument doc)
{
    var table = new DataTable("MyTable");
    table.Columns.Add("raw", typeof(string));
    var xpath = @"//th[@class='ddlabel'] | //table[not(.//*[contains(@*,'pldefault') or contains(@*,'ntdefault') or contains(@*,'bgtabon')])]";
    var nodes = doc.DocumentNode.SelectNodes(xpath);

    // Don't iterate if nodes is null.
    if (nodes != null) 
    {
        foreach (var node in nodes)
        {
            table.Rows.Add(node.InnerHtml);
        }
    }

    return table;
}
reduckted
  • 2,358
  • 3
  • 28
  • 37
1

If you really like the null-coalescing operator for its beauty (like me), try this:

foreach (var node in nodes ?? Enumerable.Empty<HtmlNode>())
{
    // whatever
}
Kryptos
  • 875
  • 8
  • 19
0

Try this one:

public DataTable tableIntoTable(HtmlDocument doc)
        {
            var table = new DataTable("MyTable");
            table.Columns.Add("raw", typeof(string));
            var xpath = @"//th[@class='ddlabel'] | //table[not(.//*[contains(@*,'pldefault') or contains(@*,'ntdefault') or contains(@*,'bgtabon')])]";
            var nodes = doc.DocumentNode.SelectNodes(xpath);
            if (nodes != null && nodes.Count > 0)
            {
                foreach (var node in nodes)
                {
                    table.Rows.Add(node.InnerHtml);
                }
            }

            return table;
        }
-2

Do not add any check if you are iterating nodes using foreach loop. It will simply skip the loop if nodes is null.

public DataTable tableIntoTable(HtmlDocument doc)
{


  var table = new DataTable("MyTable");
    table.Columns.Add("raw", typeof(string));
    var xpath = @"//th[@class='ddlabel'] | //table[not(.//*[contains(@*,'pldefault') or contains(@*,'ntdefault') or contains(@*,'bgtabon')])]";
    var nodes = doc.DocumentNode.SelectNodes(xpath);

    foreach (var node in nodes)
    {
        table.Rows.Add(node.InnerHtml);
    }

  return table;
}
Ishtiaq
  • 980
  • 2
  • 6
  • 21
  • 1
    `foreach` still throws `NullRefenceException` if the enumeration is `null`. It will only skip it if the enumeration is empty. Not exactly the same. – Kryptos May 21 '15 at 12:03
-2

I think your problem is a line above when you are getting the nodes. Just declare the node nullable.

public DataTable tableIntoTable(HtmlDocument doc)
{ 
    var table = new DataTable("MyTable");
    table.Columns.Add("raw", typeof(string));
    var xpath = @"//th[@class='ddlabel'] | //table[not(.//*contains(@*,'pldefault') or contains(@*,'ntdefault') or contains(@*,'bgtabon')])]";
    HtmlAgilityPack.HtmlNode? node = doc.DocumentNode.SelectNodes(xpath);

    foreach (var node in nodes)
    {
        table.Rows.Add(node.InnerHtml);
    }
    return table;
}
Bogdan Banciu
  • 169
  • 1
  • 6
  • `SelectNodes` returns a `HtmlNodeCollection`, not a `HtmlNode`. It's also a class, so it's not nullable. – reduckted May 21 '15 at 12:07