我使用以下代码从XML文件中提取信息。但是如果节点不存在,我会收到NullReferenceException错误。我认为使用LINQ不应该发生这种情况。但就此而言,我对LINQ和XML非常陌生。所以我添加了一个我从here找到的扩展方法。但我仍然得到错误。有人可以告诉我我错过了什么吗?
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());
}
}
}
}
答案 0 :(得分:2)
这是一个问题:
ClaimProbableAmount = (string)node.Element("ClaimsDownloadInfo").Element("ClaimsOccurrence").Element("ProbableIncurredAmt").Element("Amt").ElementValueNull()
由于您使用的是Element()
,因此存在获得NRE的风险。 Element()
返回指定元素的第一个实例或null。你在兔子洞里跳得太远了。
您可以通过多种方式解决此问题,更改除最后一个以外的所有来电以使用Elements()
。这次它只会返回一个空集合,如果它们不存在的话。或者使用其他方法,例如等效的xpath查询。
答案 1 :(得分:1)
ElementValueNull
中的问题几乎肯定是不 ...之前的Element
调用之一返回null。您正在调用实例方法(XContainer.Element()
)并且这是一个非常普通的实例方法 - 如果它在空引用上调用,它将像任何其他实例方法一样抛出异常将
避免这种情况的一个选择是反复使用Elements
- 这样你最终会得到一个空序列,而不是空引用。最后使用FirstOrDefault
获取单个XElement
引用或null
。
此外:
StringBuilder
时,使用ToString()
没有任何好处。我会将您的查询编写为:
var amounts = doc.Elements("ClaimsSvcRs").Elements("ClaimDownloadRs")
.Select(x => (string) x.Elements("ClaimsDownloadInfo")
.Elements("ClaimsOccurrence")
.Elements("ProbableIncurredAmt")
.Elements("Amt")
.FirstOrDefault() ?? "");
(请注意,您的扩展方法不需要 - 如果输入为string
,则显式转换为null
将返回null
,然后空归合运算符将采用谨慎使用""
代替null
。)
答案 2 :(得分:0)
如果任何父元素为null
(即ClaimsDownloadInfo
,ClaimsOccurance
等),那么您将获得NullReferenceException
。 ElementValueNull
扩展方法不会神奇地捕获它。您必须一次获取一个元素,并确认每个元素都不为空:
var claimsDownloadInfo = node.Element("ClaimsDownloadInfo");
if(claimsDownloadInfo != null)
{
var claimsOccurance = claimsDownloadInfo.Element("ClaimsOccurrence");
if(claimsOccurance != null)
{
//etc
}
}