You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用XDocument结合可空类型与??运算符单行读取指定XML属性值

问题描述

开发环境

  • 编译器:Visual Studio 2019
  • 框架:.NET 2.1

场景说明

现有如下结构的XML文件:

<root>
  <data>
        <AdditionalOrderInfo>
            <AdditionalInfoItem key="{4567B566-A0A2-4214-B7E7-814FE179CDFC}" value="ScanItDental"/>
            <AdditionalInfoItem key="GlobalOrderID" value="EDC531BE6A0D4DC5BFEA0C6081D9F26B"/>
            <AdditionalInfoItem key="CreatedIn" value="2.20.1.2"/>
        </AdditionalOrderInfo>  
    </data>
</root>

需要筛选出key为指定值的AdditionalInfoItem节点,读取对应的value属性值。
最初尝试使用可空类型和空合并运算符??实现:

var additionalOrderInfo = document.Descendants(ns + "AdditionalOrderInfo").First();
var value = additionalOrderInfo.Descendants(ns + "AdditionalInfoItem")?.Where(el => el.Attribute("key").Value == "SomeKey")?.First()?.Attribute("value")?.Value ?? "";

但当指定的key不存在时,代码抛出异常:

序列不包含任何元素
目前使用foreach循环实现了需求:

var additionalOrderInfo = document.Descendants(ns + "AdditionalOrderInfo").First();
foreach (var item in additionalOrderInfo.Descendants(ns + "AdditionalInfoItem"))
{
    switch (item.Attribute("key").Value)
    {
        case "SomeKey1":
            Order.SomeKey1 = item.Attribute("value").Value;
            break;
        case "SomeKey2":
            Order.SomeKey2 = item.Attribute("value").Value;
            break;
    }
}

提问:有没有办法可以不使用foreach循环,通过单行代码实现上述需求?

解决方案

错误原因

之前的代码报错是因为First()方法在筛选结果为空时会直接抛出「序列不包含任何元素」的异常,替换为FirstOrDefault()即可,该方法在序列为空时会返回null,搭配空传播运算符就能避免报错。

单个key取值的单行实现

var value = additionalOrderInfo.Descendants(ns + "AdditionalInfoItem").FirstOrDefault(el => (string)el.Attribute("key") == "SomeKey")?.Attribute("value")?.Value ?? string.Empty;

说明:这里将el.Attribute("key").Value替换为强制转换(string)el.Attribute("key"),还能额外避免节点不存在key属性时触发的空引用异常。

多个key批量赋值的无循环实现

如果需要同时给多个属性赋值,可以先将所有节点转换为字典,再直接取值:

// 仅需一行完成转换,后续取值无需遍历
var infoDict = additionalOrderInfo.Descendants(ns + "AdditionalInfoItem").ToDictionary(el => (string)el.Attribute("key"), el => (string)el.Attribute("value"));
// 取值赋值
Order.SomeKey1 = infoDict.TryGetValue("SomeKey1", out var val1) ? val1 : string.Empty;
Order.SomeKey2 = infoDict.TryGetValue("SomeKey2", out var val2) ? val2 : string.Empty;

内容的提问来源于stack exchange,提问作者McNets

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 10:24:03