如何将XML子节点的两个属性合并存入List<>?
解决XML节点属性合并存入List的问题
原代码的核心问题是遍历每个属性时都创建并添加一个listItems对象,导致currency和rate各自占一条记录。正确逻辑应该是对每个包含这两个属性的节点,一次性创建一个对象并添加到列表中。
修复原有递归方法
修改遍历逻辑,针对每个节点先检查是否同时存在currency和rate属性,再创建对象添加到列表:
static void ecbXmlNanny(XmlNode ecbNode, List<listItems> result) { if (ecbNode != null && ecbNode.HasChildNodes) { foreach (XmlNode node in ecbNode.ChildNodes) { if (node.Attributes != null) { // 检查当前节点是否同时包含目标属性 XmlAttribute currencyAttr = node.Attributes["currency"]; XmlAttribute rateAttr = node.Attributes["rate"]; if (currencyAttr != null && rateAttr != null) { listItems item = new listItems(); item.ecbCurrency = currencyAttr.Value; // 用TryParse避免格式错误导致的异常 if (Decimal.TryParse(rateAttr.Value, out decimal rateValue)) { item.ecbRate = rateValue; result.Add(item); } } } // 递归处理子节点 ecbXmlNanny(node, result); } } }
推荐:用LINQ to XML实现更简洁的逻辑
LINQ to XML处理XML文档更高效易读,无需递归遍历,直接查询目标节点:
首先确保引用System.Xml.Linq命名空间,然后执行以下代码:
// 加载目标XML文档 XDocument ecbDoc = XDocument.Load("https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml"); // 原XML包含默认命名空间,必须指定才能正确查询节点 XNamespace ns = "http://www.ecb.int/vocabulary/2002-08-01/eurofxref"; // 查询所有带currency和rate属性的Cube节点,转换为listItems列表 List<listItems> currencyList = ecbDoc.Descendants(ns + "Cube") .Where(node => node.Attribute("currency") != null && node.Attribute("rate") != null) .Select(node => new listItems { ecbCurrency = node.Attribute("currency").Value, ecbRate = Decimal.Parse(node.Attribute("rate").Value) }) .ToList();
注意事项
- 必须指定XML命名空间:原XML文档使用了默认命名空间,不指定会导致查询不到目标节点。
- 异常处理:建议用
Decimal.TryParse替代直接Parse,避免rate属性值格式错误导致程序崩溃。
这样处理后,currencyList中的每个元素都会同时包含currency和rate值,列表长度与目标节点数量一致(约30条),后续可以直接将该列表序列化为JSON传递给服务。
内容的提问来源于stack exchange,提问作者jindo
相关产品推荐
相关产品推荐

