如何用XDocument一次性读取XML中可变数量的destination属性?
如何读取XML中数量可变的destination属性?
嘿,我来帮你解决这个问题——其实不用纠结正则或者手动循环,用LINQ to XML就能轻松搞定这些可变数量的destination属性,而且代码还很简洁。先看看你的场景:
你的XML示例
<?xml version="1.0" encoding="utf-8" ?> <SaleGroupsFiles> <SaleGroup id="1" active="true" name="US"> <files location="c:\mypath\" fileType="pdf" destination1="outputpath1" destination2="outputpath2"> </files> </SaleGroup> <SaleGroup id="2" active="true" name="Canada"> <files location="c:\mypath\" fileType="pdf" destination1="outputpath1" destination2="outputpath2" destination3="outputpath3"> </files> </SaleGroup> </SaleGroupFiles>
你已实现的C#代码
public class SaleGroup { public int Id { get; set; } public bool Active { get; set; } public string Name { get; set; } public SaleFile File { get; set; } } public class SaleFile { public string Location { get; set; } public string FileType { get; set; } public string[] Destination { get; set; } } static List<string> GetSettings(string path) { var document = XDocument.Load(path); var root = document.Root; var results = root .Descendants("SaleGroup") .Select(element => new SaleGroup() { Active = Convert.ToBoolean(element.Attribute("active").Value), Id = Convert.ToInt32(element.Attribute("id").Value), Name = element.Attribute("name").Value, File = new SaleFile() { FileType = element.Descendants("files").Single().Attribute("fileType").Value, Location = element.Descendants("files").Single().Attribute("location").Value } }) .ToList(); }
解决方案:用LINQ to XML直接筛选属性(无需正则或手动循环)
完全不用正则,XDocument本身就可以轻松筛选出所有以destination开头的属性,一次性转成数组。你只需要在SaleFile的初始化里添加对Destination的赋值,修改后的代码如下:
static List<SaleGroup> GetSettings(string path) // 注意:原代码返回类型写错了,应该是List<SaleGroup> { var document = XDocument.Load(path); var root = document.Root; var results = root .Descendants("SaleGroup") .Select(element => new SaleGroup() { Active = Convert.ToBoolean(element.Attribute("active").Value), Id = Convert.ToInt32(element.Attribute("id").Value), Name = element.Attribute("name").Value, File = new SaleFile() { FileType = element.Descendants("files").Single().Attribute("fileType").Value, Location = element.Descendants("files").Single().Attribute("location").Value, // 核心逻辑:筛选、排序、提取destination属性值 Destination = element.Descendants("files").Single() .Attributes() .Where(attr => attr.Name.LocalName.StartsWith("destination")) // 按属性名后的数字排序,确保顺序正确(避免destination10排在destination2前面) .OrderBy(attr => int.Parse(attr.Name.LocalName.Replace("destination", ""))) .Select(attr => attr.Value) .ToArray() } }) .ToList(); return results; }
关键逻辑说明:
- 筛选属性:通过
Where(attr => attr.Name.LocalName.StartsWith("destination"))找出所有以destination开头的属性 - 排序:提取属性名里的数字(比如从
destination2中得到2),按数字排序,保证顺序是destination1→destination2→destination3...,避免字符串排序导致的顺序错误 - 提取值:把筛选后的属性值转成数组,赋值给
SaleFile.Destination
为什么不推荐正则?
正则处理XML很容易踩坑——比如如果属性值里包含特殊字符、或者XML结构有换行/缩进变化,正则就可能匹配出错。用LINQ to XML是更安全、更符合XML规范的做法,而且代码可读性更高。
关于循环的问题
上面的代码里,LINQ的Where、OrderBy、Select已经帮你完成了遍历筛选的逻辑,你不用手动写for/foreach循环,代码更简洁易维护。
内容的提问来源于stack exchange,提问作者anjulis
相关产品推荐
相关产品推荐

