I'm using the below code to pull out info from an XML file. But if node isn't present I get a NullReferenceException error. I thought that wasn't supposed to happen with using LINQ. But I'm very new to LINQ and XML for that matter. So I added an extention method I found from here. But I still get the error. Can someone tell me what I'm missing please?
using System;
using System.Text;
using System.Windows.Forms;
using System.Linq;
using System.Xml.Linq;
public static class XElementExtensionMethod
{
public static string ElementValueNull(this XElement element)
{
if (element != null)
{
return element.Value;
}
else
{
return string.Empty;
}
}
}
namespace XMLReader
{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
private void frmMain_Load(object sender, EventArgs e)
{
string file = @"c:\users\jim\desktop\XMLData - Copy.xml";
XElement doc = XElement.Load(file);
StringBuilder sb = new StringBuilder();
var nodes = from node in doc.Elements("ClaimsSvcRs").Elements("ClaimDownloadRs")
select new
{
ClaimProbableAmount = (string)node.Element("ClaimsDownloadInfo").Element("ClaimsOccurrence").Element("ProbableIncurredAmt").Element("Amt").ElementValueNull()
};
foreach (var node in nodes)
{
sb.Append("AMOUNT = ").Append(node.ClaimProbableAmount);
MessageBox.Show(sb.ToString());
}
}
}
}
The problem is almost certainly not in ElementValueNull
... it's that one of the earlier Element
calls is returning null. You're calling an instance method (XContainer.Element()
) and that's a perfectly ordinary instance method - if it's called on a null reference, that will throw an exception just like any other instance method will.
One option to avoid this is to use Elements
repeatedly instead - that way you'll end up with an empty sequence, instead of a null reference. Use FirstOrDefault
at the end to get a single XElement
reference or null
.
Additionally:
StringBuilder
when you're calling ToString()
on each iteration of the loop.I would write your query as:
var amounts = doc.Elements("ClaimsSvcRs").Elements("ClaimDownloadRs")
.Select(x => (string) x.Elements("ClaimsDownloadInfo")
.Elements("ClaimsOccurrence")
.Elements("ProbableIncurredAmt")
.Elements("Amt")
.FirstOrDefault() ?? "");
(Note the lack of a need for your extension method - the explicit conversion to string
will return null
if the input is null
, and then the null-coalescing operator will take care of using ""
instead of null
.)
See more on this question at Stackoverflow