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

如何使用C#递归打印XML树属性与元素并修复代码输出异常

问题原因

代码运行无输出是因为存在以下核心错误:

  • XML节点选择逻辑错误:XML结构中<AUTHORS>是父容器,内部直接嵌套<AUTHOR>节点,<AUTHOR>节点下不存在<AUTHORS>子节点,doc.Descendants("AUTHOR").Elements("AUTHORS")的查询结果是空集合,没有任何数据可加载。
  • 节点取值方式错误:FIRSTNAME、LASTNAME是<AUTHOR>的子元素,不是节点属性,用Attribute()方法取值会触发空引用异常。
  • 模型定义缺失:需求要求存储的id、obs、responsible三个属性没有在Author类中定义,不满足存储要求。
  • 方法调用与作用域错误:PrintAutors是实例方法,既没有在程序入口Main中被调用,方法内部也无法访问Main中定义的局部变量authors。
  • 空值处理缺失:部分<AUTHOR>节点没有responsible属性,直接取Value会抛异常;Children集合为空时调用无种子值的Aggregate方法,也会抛出序列无元素的错误。
修正后实现

第一步:补全Author模型类

新增需要存储的三个属性,同时优化ToString方法的空值兼容逻辑:

public class Author
{
    public string Id { get; set; }
    public string Obs { get; set; }
    // responsible为可空属性,部分节点无该值
    public string? Responsible { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public List<Author> Children { get; set; } = new();

    public override string ToString()
    {
        var baseInfo = $"ID: {Id}, OBS: {Obs}, Responsible: {Responsible ?? "无"}, 姓名: {FirstName} {LastName}";
        if (Children.Any())
        {
            var childInfo = string.Join("\n  ", Children.Select(c => c.ToString()));
            baseInfo += $"\n  子作者:\n  {childInfo}";
        }
        return baseInfo;
    }
}

第二步:修正XML加载与打印逻辑

调整节点查询路径,区分属性和子元素的取值方式,补充空值保护,直接在入口调用打印逻辑:

using System.Xml.Linq;

class Solution
{
    public static string xmlFilePath = "authors.xml";

    public static void Main()
    {
        XDocument doc = XDocument.Load(xmlFilePath);
        // 正确查询路径:先取根级AUTHORS节点,再查询其下所有AUTHOR直接子节点
        var authorElements = doc.Element("AUTHORS")?.Elements("AUTHOR") ?? Enumerable.Empty<XElement>();
        List<Author> authors = LoadAuthors(authorElements);
        
        // 遍历打印所有作者信息
        foreach (var author in authors)
        {
            Console.WriteLine(author.ToString());
            Console.WriteLine("------------------------");
        }
    }

    public static List<Author> LoadAuthors(IEnumerable<XElement> authorElements)
    {
        return authorElements.Select(x => new Author()
        {
            // 读取节点属性值
            Id = x.Attribute("id")?.Value ?? string.Empty,
            Obs = x.Attribute("obs")?.Value ?? string.Empty,
            Responsible = x.Attribute("responsible")?.Value,
            // 读取子元素值
            FirstName = x.Element("FIRSTNAME")?.Value ?? string.Empty,
            LastName = x.Element("LASTNAME")?.Value ?? string.Empty,
            // 保留嵌套作者加载逻辑,兼容后续XML结构扩展
            Children = LoadAuthors(x.Elements("AUTHORS").Elements("AUTHOR"))
        }).ToList();
    }
}
运行效果

程序启动后控制台会输出每个作者的完整信息,示例输出如下:

ID: _03131488, OBS: 0, Responsible: 1, 姓名: Dickson Richard
------------------------
ID: _03135122, OBS: 0, Responsible: 无, 姓名: Ancelotti Carlo
------------------------
ID: _0312C456, OBS: 0, Responsible: 1, 姓名: Howard Patricia
------------------------

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 20:45:38