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

如何将嵌套XML读取到自定义类,替代匿名类型以实现传参?

问题描述

我有一个项目,将构建成功标准以XML格式存储,需要和日志数据对比判断构建是否成功。目前用LINQ读取XML得到的是匿名类型集合,里面的列表没法传递给ParseLogFile1方法,现在想把XML数据读取到自己定义的类里,避免匿名类型,方便后续调用日志解析方法。

现有LINQ代码(匿名类型):

var results1 =
xmlDoc2.Descendants("build")
.SelectMany(b => b.Descendants("Process")
.Select(p => new
{
    buildMach = b.Element("BuildMachine").Value,
    p1 = p.Element("ProcessName").Value,
    startTimeHeader = p.Element("startTimeHeader").Value,
    conditions = p.Descendants("Condition")
        .Select(c => new
        {
            cName = (string)c.Attribute("name")?.Value,
            cValue = (string)c.Attribute("value")?.Value
        })
        .ToList(),
    successCriteria = p.Descendants("SuccessCriteria")
        .Select(sc => new
        {
            f1 = (string)sc.Element("field")?.Value,
            c1 = (string)sc.Element("comparison")?.Value,
            v1 = (string)sc.Element("value")?.Value
        })
        .ToList()
})).ToList();

// 这里无法传递匿名类型的列表参数
foreach (var currentItem in results1)
{
   ParseLogFile1(codeFreezeTime, currentItem.startTimeHeader, currentItem.buildMach, currentItem.p1, currentItem.conditions, currentItem.successCriteria);
}

自定义类(存在编译/逻辑错误):

// SuccessCriterium.cs
public class SuccessCriterium
{
   public SuccessCriterium()
      List<SuccessCriteria> successCriteria = new List<SuccessCriteria>();
}

// SuccessCriteria.cs
public class SuccessCriteria
{
    public SuccessCriteria()
    {
        string f1 = "";
        string c1 = "";
        string v1 = "";
    }
}

// Condition.cs
public class Condition
{
    public Condition()
    {
        string cName = "";
        string cValue = "";
    }
}

// Conditions.cs
public class Condition
{
    public Condition()
    {
        List<Condition> conditions = new List<Condition>();
    }
}

public class ProcessValidationInfo
{
    public ProcessValidationInfo()
    {
        string codeFreezeTime = "";
        string startTimeHeader = "";
        string buildMach = "";
        string p1 = "";
        Conditions conditions = new Conditions();
        SuccessCriterium successCriterium = new SuccessCriterium();
    }
}

解决步骤

1. 修正自定义类的错误

你的类定义存在两个核心问题:构造函数里的变量都是局部变量(无法外部访问/赋值);Conditions.cs重复定义了Condition类导致编译冲突。重新定义类如下:

// 单个条件实体类
public class Condition
{
    public string CName { get; set; } = string.Empty;
    public string CValue { get; set; } = string.Empty;
}

// 条件集合容器类
public class Conditions
{
    public List<Condition> Items { get; set; } = new List<Condition>();
}

// 单个成功标准实体类
public class SuccessCriteria
{
    public string Field { get; set; } = string.Empty;
    public string Comparison { get; set; } = string.Empty;
    public string Value { get; set; } = string.Empty;
}

// 成功标准集合容器类
public class SuccessCriterium
{
    public List<SuccessCriteria> Items { get; set; } = new List<SuccessCriteria>();
}

// 顶层流程验证信息类
public class ProcessValidationInfo
{
    public string CodeFreezeTime { get; set; } = string.Empty;
    public string StartTimeHeader { get; set; } = string.Empty;
    public string BuildMachine { get; set; } = string.Empty;
    public string ProcessName { get; set; } = string.Empty;
    public Conditions Conditions { get; set; } = new Conditions();
    public SuccessCriterium SuccessCriterium { get; set; } = new SuccessCriterium();
}

2. 修改LINQ查询,映射到自定义类

把匿名类型替换为强类型,直接在Select中实例化自定义类并赋值:

var results1 = xmlDoc2.Descendants("build")
    .SelectMany(b => b.Descendants("Process")
        .Select(p => new ProcessValidationInfo
        {
            BuildMachine = b.Element("BuildMachine")?.Value ?? string.Empty,
            ProcessName = p.Element("ProcessName")?.Value ?? string.Empty,
            StartTimeHeader = p.Element("startTimeHeader")?.Value ?? string.Empty,
            // 映射条件集合
            Conditions = new Conditions
            {
                Items = p.Descendants("Condition")
                    .Select(c => new Condition
                    {
                        CName = c.Attribute("name")?.Value ?? string.Empty,
                        CValue = c.Attribute("value")?.Value ?? string.Empty
                    })
                    .ToList()
            },
            // 映射成功标准集合
            SuccessCriterium = new SuccessCriterium
            {
                Items = p.Descendants("SuccessCriteria")
                    .Select(sc => new SuccessCriteria
                    {
                        Field = sc.Element("field")?.Value ?? string.Empty,
                        Comparison = sc.Element("comparison")?.Value ?? string.Empty,
                        Value = sc.Element("value")?.Value ?? string.Empty
                    })
                    .ToList()
            }
        }))
    .ToList();

3. 调用ParseLogFile1方法

现在results1是List<ProcessValidationInfo>强类型集合,可直接传递列表参数:

foreach (var currentItem in results1)
{
    ParseLogFile1(
        codeFreezeTime, 
        currentItem.StartTimeHeader, 
        currentItem.BuildMachine, 
        currentItem.ProcessName, 
        currentItem.Conditions.Items, 
        currentItem.SuccessCriterium.Items
    );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 18:54:55