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
相关产品推荐
相关产品推荐

