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

C#递归读取目录XML文件并提取指定节点生成CSV求助

解决XML节点读取问题:无法获取的值

你的代码读不到<CodiceValore>主要是两个层级定位错误导致的,完全不需要递归方法,调整节点访问路径就能解决,我帮你修正并优化代码:

问题分析

  1. 节点遍历层级错误:你当前遍历的是<DatiBeniServizi>节点,但实际需要提取数据的是它下面的每个<DettaglioLinee>子节点
  2. 嵌套节点访问错误:<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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:00:03