如何将嵌套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
相关产品推荐
相关产品推荐

