如何用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
相关产品推荐
相关产品推荐

