【问题标题】:XML to LINQ with Checking Null Elements带有检查空元素的 XML 到 LINQ
【发布时间】:2013-03-28 02:22:16
【问题描述】:

我面临的情况是使用 Linq 将 XML 文档解析为对象。在解析期间,我正在检查以确保元素不为空,然后再继续解析它们的值。有没有办法简化这句话?

  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 语句。

或者也许我做错了,有更好的方法!

【问题讨论】:

    标签: c# linq xml-parsing


    【解决方案1】:

    你可以替换

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

    (int)x.Element("nodeName")
    

    它也适用于stringintdoubledecimalbooluintDateTimeNullable

    【讨论】:

    • 我在原始代码中没有看到对 int.Parse 的任何调用...诚然无法编译。
    • 我认为原始代码根本无法编译,所以我添加了int.Parse()
    【解决方案2】:

    一个简单的选择是使用Elements 而不是Element - 如果元素不存在,它将返回一个零长度序列。所以你可以使用:

    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...)

    【讨论】:

    • 你为什么要做一个.Select(x => (int) x)?不应该是 .Select(y = (int) y.Value) 吗?由于我们仍然需要获取元素的值,并且上面还声明了 x,所以它需要是一个不同的变量?
    • @cgatian:是的,错过了重复的变量名。修复。
    • .Value 而不是 y 怎么样。那不是在 XElement 上进行投射吗?或者也许我错过了什么。
    • @cgatian:这将尝试将string 转换为int,这是行不通的。您可以使用int.Parse(y.Value),但我更喜欢XElement 提供的显式转换。
    【解决方案3】:

    在 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();
    

    您可以阅读更多 here 部分标题为空条件运算符。

    【讨论】:

    • 这很好。它帮助我将笨重的多行辅助方法简化为一行:return orgElem.Element("subs")?.Elements("organization") ?? Enumerable.Empty<XElement>();
    猜你喜欢
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多