C# 检查空元素的XML到LINQ

C# 检查空元素的XML到LINQ,c#,linq,xml-parsing,C#,Linq,Xml Parsing,我面临的情况是使用Linq将XML文档解析为对象。在解析过程中,在继续解析元素的值之前,我会检查元素是否为null。有没有办法简化这句话 var variable = (from x in xdoc.Descendants("Root") select new AccountingResponse { NetCharge = x.Element("Charges") != nul

我面临的情况是使用Linq将XML文档解析为对象。在解析过程中,在继续解析元素的值之前,我会检查元素是否为null。有没有办法简化这句话

  var variable = (from x in xdoc.Descendants("Root")
                 select new AccountingResponse
                 {      
                 NetCharge = x.Element("Charges") != null && x.Element("Charges").Element("NetCharge") != null ? x.Element("Charges").Element("NetCharge").Value : "0",
                 TotalCharge = x.Element("Charges") != null && x.Element("Charges").Element("TotalCharge") != null ? x.Element("Charges").Element("TotalCharge").Value : "0"
                 }).SingleOrDefault();
总之,我不想继续检查每一行上是否存在节点。我知道我可以在解析之前测试节点是否存在,但是可能需要解析其他数据来创建AccountingResponse,我希望避免一次只解析一部分XML的if语句

也许我做的完全错误,还有更好的方法

您可以替换

x.Element("nodeName") != null : int.Parse(x.Element("nodeName").Value) : 0


它适用于
string
int
double
decimal
bool
uint
DateTime
Nullable

一个简单的选择是使用
元素
,而不是
元素
——如果元素不存在,它将返回零长度序列。因此,您可以使用:

from x in xdoc.Descendants("Root")
select new AccountingResponse
{      
    NetCharge = x.Elements("Charges")
                 .Elements("NetCharge")
                 .Select(y => (int) y)
                 .FirstOrDefault(),
    TotalCharge = x.Elements("Charges")
                   .Elements("TotalCharge")
                   .Select(y => (int) y)
                   .FirstOrDefault(),
}).SingleOrDefault();
(请注意,您的原始代码不会编译,因为
Value
是一个字符串,而0是一个int…)

在C#6.0中,您可以使用一元空条件运算符
?。
在您的示例中应用后,它将如下所示:

var variable = (from x in xdoc.Descendants("Root")
                select new
                {
                    NetCharge = x.Element("Charges")?.Element("NetCharge")?.Value ?? "0",
                    TotalCharge = x.Element("Charges")?.Element("TotalCharge")?.Value ?? "0"
                }).SingleOrDefault();

您可以在标题为Null条件运算符的部分中阅读更多内容。

在原始代码中,我没有看到任何对
int.Parse
的调用。。。我认为原始代码根本无法编译,这就是为什么我添加了
int.Parse()
为什么要执行.Select(x=>(int)x)?是否应该。选择(y=(int)y.Value)??因为我们仍然需要获取元素的值,并且上面声明了x,所以它需要是一个不同的变量?@cgatian:Yup,错过了重复的变量名。修正。关于。值而不仅仅是y。那不是在一个元素上铸造的吗?或者我遗漏了什么。@cgatian:那可能是试图将
字符串
转换为
int
,但这不起作用。您可以使用
int.Parse(y.Value)
,但我更喜欢
XElement
提供的显式转换。这很好。它帮助我将一个笨拙的多行助手方法简化为一行:
returnorgelem.Element(“subs”)?.Elements(“organization”)??Enumerable.Empty()
var variable = (from x in xdoc.Descendants("Root")
                select new
                {
                    NetCharge = x.Element("Charges")?.Element("NetCharge")?.Value ?? "0",
                    TotalCharge = x.Element("Charges")?.Element("TotalCharge")?.Value ?? "0"
                }).SingleOrDefault();