C#递归读取目录XML文件并提取指定节点生成CSV求助
解决XML节点读取问题:无法获取的值
你的代码读不到<CodiceValore>主要是两个层级定位错误导致的,完全不需要递归方法,调整节点访问路径就能解决,我帮你修正并优化代码:
问题分析
- 节点遍历层级错误:你当前遍历的是
<DatiBeniServizi>节点,但实际需要提取数据的是它下面的每个<DettaglioLinee>子节点 - 嵌套节点访问错误:
<CodiceValore>是<CodiceArticolo>的子节点,不是<DettaglioLinee>的直接子节点,直接用x.Element("CodiceValore")会返回null
修正后的完整代码
using System; using System.Text; using System.Xml.Linq; using System.IO; using System.Linq; // 假设你已经加载了xDocument,比如: // var xDocument = XDocument.Load("你的XML文件路径"); // 1. 正确定位节点并提取数据 var results = xDocument.Descendants("DatiBeniServizi") .Elements("DettaglioLinee") // 遍历每个数据行节点 .Select(dettaglio => new { // 先获取CodiceArticolo节点,再访问它的CodiceValore子节点 Codice = (string)dettaglio.Element("CodiceArticolo")?.Element("CodiceValore"), Descrizione = (string)dettaglio.Element("Descrizione"), Quantita = (string)dettaglio.Element("Quantita"), PrezzoUnitario = (string)dettaglio.Element("PrezzoUnitario"), AliquotaIVA = (string)dettaglio.Element("AliquotaIVA") }) .ToList(); // 2. 生成CSV(优化拼接逻辑,避免语法错误) var dataToBeWritten = new StringBuilder(); // 可选:添加CSV表头,让文件更易读 dataToBeWritten.AppendLine("Codice;Descrizione;Quantita;PrezzoUnitario;AliquotaIVA;;"); foreach (var item in results) { // 用String.Join简化字段拼接,同时处理空值 var csvLine = string.Join(";", item.Codice ?? string.Empty, item.Descrizione ?? string.Empty, item.Quantita ?? string.Empty, item.PrezzoUnitario ?? string.Empty, item.AliquotaIVA ?? string.Empty, "0", "0" ); dataToBeWritten.AppendLine(csvLine); } // 3. 写入文件 var testPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "test.csv"); File.WriteAllText(testPath, dataToBeWritten.ToString()); Console.WriteLine(dataToBeWritten.ToString()); Console.ReadLine();
关键优化点
- 使用
?.空值运算符:防止某个<DettaglioLinee>节点缺失<CodiceArticolo>时抛出空引用异常 - 用
String.Join替代重复的Append:减少代码冗余,避免手动拼接时的语法错误(比如你原代码里的Append(";";是语法错误) - 空值处理:用
?? string.Empty把null替换为空字符串,避免CSV中出现null文本 - 精准节点定位:从
<DatiBeniServizi>直接获取<DettaglioLinee>子节点,比Descendants更高效
关于递归的说明
完全不需要递归!递归一般用于处理未知层级的嵌套节点(比如节点结构不固定,有多层嵌套),而你的XML结构是固定的,直接通过节点层级访问就能拿到需要的数据,递归反而会增加不必要的复杂度。
内容的提问来源于stack exchange,提问作者Stefano Rosso
相关产品推荐
相关产品推荐

