C#中ListView数据按人员ID排序生成符合指定XSD结构XML的问题
解决思路与实现方案
核心逻辑是先归集数据再生成XML,不要边遍历ListView边写入XML节点,避免同人员多记录分散的问题。
实现步骤
- 第一步:从ListView中读取所有数据,转换为强类型集合
- 第二步:使用LINQ按人员ID分组,同时支持按ID排序
- 第三步:遍历分组后的集合生成XML结构
- 第四步:可选做XSD一致性校验
代码示例
using System.Linq; using System.Xml.Linq; using System.Collections.Generic; using System.Windows.Forms; // WinForm环境引用 // 1. 定义数据模型,字段根据你的实际业务调整 public class PersonRecord { public string PersonId { get; set; } public string Name { get; set; } public DateTime RecordDate { get; set; } public string Post { get; set; } // 其他你需要的字段 } // 2. 读取ListView数据转成强类型集合 List<PersonRecord> allRecords = new List<PersonRecord>(); foreach (ListViewItem item in listView1.Items) { allRecords.Add(new PersonRecord { PersonId = item.SubItems[0].Text, // 人员ID所在的列索引,根据实际调整 Name = item.SubItems[1].Text, RecordDate = DateTime.Parse(item.SubItems[2].Text), Post = item.SubItems[3].Text // 其他字段赋值 }); } // 3. 按人员ID排序+分组,同人员的所有记录会被归集到同一分组下 var personGroups = allRecords .OrderBy(r => r.PersonId) // 按人员ID排序,按需调整排序规则 .GroupBy(r => r.PersonId); // 4. 生成XML结构,节点名根据你的XSD调整 XNamespace ns = "http://你的XSD定义的命名空间"; // 没有命名空间可删除 XDocument xDoc = new XDocument( new XDeclaration("1.0", "utf-8", null), new XElement(ns + "PersonnelData", new XAttribute("Year", "你传入的年份参数"), // 遍历每个人员分组生成节点 from group in personGroups select new XElement(ns + "Person", new XElement(ns + "PersonId", group.Key), new XElement(ns + "Name", group.First().Name), // 同人员姓名一致,取第一条即可 // 生成该人员的所有记录节点 new XElement(ns + "Records", from record in group select new XElement(ns + "Record", new XElement(ns + "RecordDate", record.RecordDate.ToString("yyyy-MM-dd")), new XElement(ns + "Post", record.Post) // 其他记录字段 ) ) ) ) ); // 5. 保存XML文件 xDoc.Save("输出路径/personnel_data.xml"); // 可选:XSD校验逻辑 /* XmlSchemaSet schemas = new XmlSchemaSet(); schemas.Add(ns, "你的XSD文件路径"); xDoc.Validate(schemas, (o, e) => { // 校验错误处理逻辑 Console.WriteLine($"XSD校验错误:{e.Message}"); }); */
注意事项
- ListView的SubItems索引需要和你实际列的顺序对应,避免取错字段
- 如果XSD对节点顺序、数据格式有严格要求,生成XML时要严格按照XSD定义的节点顺序和数据类型赋值
- 同人员公共字段(如姓名、部门等)无需重复读取,直接取分组内第一条记录的对应值即可
内容的提问来源于stack exchange,提问作者EmirSuvalic
相关产品推荐
相关产品推荐

