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

如何用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;
}

关键逻辑说明:

  1. 筛选属性:通过Where(attr => attr.Name.LocalName.StartsWith("destination"))找出所有以destination开头的属性
  2. 排序:提取属性名里的数字(比如从destination2中得到2),按数字排序,保证顺序是destination1→destination2→destination3...,避免字符串排序导致的顺序错误
  3. 提取值:把筛选后的属性值转成数组,赋值给SaleFile.Destination

为什么不推荐正则?

正则处理XML很容易踩坑——比如如果属性值里包含特殊字符、或者XML结构有换行/缩进变化,正则就可能匹配出错。用LINQ to XML是更安全、更符合XML规范的做法,而且代码可读性更高。

关于循环的问题

上面的代码里,LINQ的Where、OrderBy、Select已经帮你完成了遍历筛选的逻辑,你不用手动写for/foreach循环,代码更简洁易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:02:24