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

如何用Linq to XML读取XML并填充C#父子对象?

问题描述

我需要读取XML文件并将数据填充到C#的Field类中(包含父对象和子列表),希望用Linq to XML实现。Field类定义如下:

public class Field
{
    public string Name { get; set; } = string.Empty;
    public List<string> Options { get; set; } = new();
    public FieldType Type { get; set; } = 0;
}

每个Field对象有两种情况:

  • 包含空的Options列表
  • 包含有值的Options列表

XML格式无法修改,简化后的内容如下:

<FieldProperties>
    <FieldName>Question 1</FieldName>
    <FieldType>1</FieldType>
</FieldProperties>
<FieldProperties>
    <FieldName>Dietaries</FieldName>
    <FieldType>9</FieldType>
</FieldProperties>
<FieldProperties>
    <FieldName>Question 2</FieldName>
    <FieldType>1</FieldType>
</FieldProperties>
<FieldProperties>
    <FieldName>Transport</FieldName>
    <FieldType>9</FieldType>
</FieldProperties>
<FieldOptions>
    <FieldName>Dietaries</FieldName>
    <Option>Dietary option 1</Option>
</FieldOptions>
<FieldOptions>
    <FieldName>Dietaries</FieldName>
    <Option>Dietary option 2</Option>
</FieldOptions>
<FieldOptions>
    <FieldName>Dietaries</FieldName>
    <Option>Dietary option 3</Option>
</FieldOptions>
<FieldOptions>
    <FieldName>Transport</FieldName>
    <Option>Transport option 1</Option>
</FieldOptions>
<FieldOptions>
    <FieldName>Transport</FieldName>
    <Option>Transport option 2</Option>
</FieldOptions>

规则说明:

  • Field类对应<FieldProperties>标签
  • 当FieldType为9时,需要通过FieldName关联对应的<FieldOptions>标签,将其中的<Option>值填充到Options列表中

我已经能遍历<FieldProperties>并填充基础属性,但不知道如何判断FieldType是否为9,以及关联获取对应的FieldOptions数据。当前代码如下:

XDocument xDocument = XDocument.Parse(xmlFields);
XNamespace xNamespace = "http://tempuri.org/FieldDefinition.xsd";
List<Field> fields =
    xDocument.Descendants(xNamespace + "FieldProperties")
        .Select(fieldProperties => new Field
        {
            Name = (string)fieldProperties.Element(xNamespace + "FieldName")!.Value,
            Type = (FieldType)Int32.Parse(fieldProperties.Element(xNamespace + "FieldType")!.Value)
        }).ToList();

return fields;
解决方案

先将所有FieldOptions按FieldName分组构建映射字典,再处理FieldProperties时快速匹配对应选项,修改后的代码如下:

XDocument xDocument = XDocument.Parse(xmlFields);
XNamespace xNamespace = "http://tempuri.org/FieldDefinition.xsd";

// 预构建FieldName到选项列表的映射,提升查询效率
var optionsMap = xDocument.Descendants(xNamespace + "FieldOptions")
    .GroupBy(opt => (string)opt.Element(xNamespace + "FieldName")!)
    .ToDictionary(
        group => group.Key,
        group => group.Select(opt => (string)opt.Element(xNamespace + "Option")!).ToList()
    );

List<Field> fields = xDocument.Descendants(xNamespace + "FieldProperties")
    .Select(fieldProps =>
    {
        string fieldName = (string)fieldProps.Element(xNamespace + "FieldName")!;
        FieldType fieldType = (FieldType)int.Parse(fieldProps.Element(xNamespace + "FieldType")!.Value);

        var field = new Field
        {
            Name = fieldName,
            Type = fieldType
        };

        // 当FieldType为9时,从映射字典中获取对应选项
        if (fieldType == (FieldType)9) // 若FieldType枚举中9对应命名值,直接用命名值更清晰
        {
            optionsMap.TryGetValue(fieldName, out var matchedOptions);
            field.Options = matchedOptions ?? new List<string>();
        }

        return field;
    })
    .ToList();

return fields;

要点说明:

  • 预分组映射:通过GroupBy和ToDictionary提前将FieldOptions按FieldName分组,避免重复遍历XML节点,优化性能。
  • 类型判断与赋值:检查FieldType是否为9,若是则从映射字典中取出对应选项,不存在则赋值空列表,保证逻辑健壮。
  • 空值安全:使用TryGetValue避免因FieldName不存在于映射字典中抛出异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 19:02:02