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

C#读取XML属性与元素报错:获取指定条件的time/value数组

解决XML读取的类型不匹配错误并实现你的需求

首先来说你遇到的CS0029错误——这问题其实很直白:你的Scenario类里把ZthList定义成了List<string>,但在LINQ查询里你给它赋值的是List<Zth>,这俩类型完全不搭,自然没法隐式转换,这就是报错的核心原因。

另外,你的数据结构设计也得调整下:每个<zth>标签下面可能有好几个<data>节点,用单个的time和value属性根本存不下所有数据;而且你要的time和value是double类型,完全没必要先转成string绕一圈。

下面是修正后的完整代码,刚好能实现你要的功能:

1. 先把数据模型类改对

// 专门存每个<data>的时间和值,用double类型
public class DataPoint
{
    public double Time { get; set; }
    public double Value { get; set; }
}

// 存<zth>的属性和它下面所有的data列表
public class Zth
{
    public string MNode { get; set; }
    public string DNode { get; set; }
    public List<DataPoint> DataPoints { get; set; }
}

// 存<scenario>的名称和符合条件的zth列表
public class Scenario
{
    public string Name { get; set; }
    public List<Zth> ZthList { get; set; }
}

这里做了几个关键调整:

  • 加了个DataPoint类,专门放每个<data>的time和value,直接用double类型,省得后续转换
  • 把Zth类里的单个time/value换成了List<DataPoint>,这样能装下多个数据项
  • 把Scenario类的ZthList改成List<Zth>,和你赋值的类型匹配上,解决类型不匹配的错误
  • 属性名用了C#规范的帕斯卡命名法,看着更舒服

2. 修正XML读取的逻辑

public class XMLReader
{
    public void ReadXml()
    {
        // 简化路径拼接,避免重复写路径片段
        string xmlPath = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, @"..\..\utils\XML\XMLFile1.xml"));
        XDocument doc = XDocument.Load(xmlPath);

        // 读取所有scenario,同时直接筛选出d_node="2"的zth
        var scenarios = (from s in doc.Root.Elements("scenario")
                        select new Scenario
                        {
                            Name = (string)s.Attribute("name"),
                            // 只保留d_node等于"2"的zth,不用后续再过滤
                            ZthList = s.Elements("zth")
                                .Where(zth => (string)zth.Attribute("d_node") == "2")
                                .Select(zth => new Zth
                                {
                                    MNode = (string)zth.Attribute("m_node"),
                                    DNode = (string)zth.Attribute("d_node"),
                                    // 把当前zth下所有<data>转成DataPoint列表
                                    DataPoints = zth.Elements("data")
                                        .Select(data => new DataPoint
                                        {
                                            Time = (double)data.Attribute("time"),
                                            Value = (double)data.Attribute("value")
                                        }).ToList()
                                }).ToList()
                        }).ToList();

        // 输出结果看看,方便验证
        Console.WriteLine("所有符合条件的场景数据:");
        foreach (var scenario in scenarios)
        {
            Console.WriteLine($"\n场景名称:{scenario.Name}");
            foreach (var zth in scenario.ZthList)
            {
                Console.WriteLine($"  Zth(m_node={zth.MNode}, d_node={zth.DNode}) 的数据:");
                foreach (var data in zth.DataPoints)
                {
                    Console.WriteLine($"    时间:{data.Time},值:{data.Value}");
                }
            }
        }
    }
}

这里的改进点:

  • 简化了文件路径的写法,不用重复拼接,更易读
  • 在读取zth的时候直接用Where筛选d_node="2"的项,比后续再过滤效率更高
  • 直接把time和value转换成double类型,一步到位
  • 加了清晰的输出逻辑,能直观看到读取到的数据

3. 顺便说下你原代码里的其他小问题

  • 原代码里var zth_d_node = scenarios.Where(x => x.ZthList.Any(r => r.d_node == "1")).ToList();:你要的是d_node="2",这里条件写错了,而且修正模型后直接在读取时筛选更合理
  • 原代码里var s_names = scenarios.Where(x => x.Element("").Value.Equals("name")).toList();:这段完全不对,Scenario是你自己定义的类,根本没有Element方法,要获取场景名称直接拿scenarios里的Name属性就行

现在运行修正后的代码,就能正确读取你需要的XML数据,那个类型不匹配的错误也解决啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 17:32:26