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

XML反序列化:将XML元素属性映射为类属性的实现问题

XML反序列化为指定类的解决方法

给定XML结构:

<data>
  <element id='abc.pqr'>1</element>
  <element id='abc.xyz'>2</element>
</data>

要反序列化为包含pqr、xyz两个字符串属性的Data类,且属性值分别对应XML中element节点的文本内容。直接用XmlRoot和XmlAttribute属性无法满足需求,因为默认序列化逻辑会把每个<element>节点当作独立对象处理,导致无法正确赋值到同一个Data实例的属性上,以下是两种可行方案:

方案一:实现IXmlSerializable接口手动解析

让Data类实现IXmlSerializable接口,手动读取XML节点并赋值:

using System;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

public class Data
{
    public string Pqr { get; set; }
    public string Xyz { get; set; }

    public XmlSchema GetSchema() => null;

    public void ReadXml(XmlReader reader)
    {
        // 跳过根节点的开始标签
        reader.ReadStartElement("data");
        
        while (reader.NodeType != XmlNodeType.EndElement)
        {
            if (reader.Name == "element")
            {
                var id = reader.GetAttribute("id");
                var value = reader.ReadElementContentAsString();
                
                // 根据id后缀匹配属性
                if (id == "abc.pqr")
                    Pqr = value;
                else if (id == "abc.xyz")
                    Xyz = value;
            }
            else
            {
                // 跳过未知节点
                reader.Skip();
            }
        }
        
        // 读取根节点的结束标签
        reader.ReadEndElement();
    }

    public void WriteXml(XmlWriter writer)
    {
        // 如果需要序列化回XML,可在此实现写入逻辑
        writer.WriteStartElement("element");
        writer.WriteAttributeString("id", "abc.pqr");
        writer.WriteString(Pqr);
        writer.WriteEndElement();
        
        writer.WriteStartElement("element");
        writer.WriteAttributeString("id", "abc.xyz");
        writer.WriteString(Xyz);
        writer.WriteEndElement();
    }
}

使用方式:

var serializer = new XmlSerializer(typeof(Data));
using var reader = XmlReader.Create("your-xml-file-path.xml");
var data = (Data)serializer.Deserialize(reader);

方案二:先反序列化为中间类再映射

先定义一个对应XML结构的中间类,反序列化后再将数据映射到目标Data类:

using System.Collections.Generic;
using System.Xml.Serialization;

// 中间类,匹配XML的结构
[XmlRoot("data")]
public class DataXml
{
    [XmlElement("element")]
    public List<Element> Elements { get; set; } = new List<Element>();
}

public class Element
{
    [XmlAttribute("id")]
    public string Id { get; set; }
    
    [XmlText]
    public string Value { get; set; }
}

// 目标类
public class Data
{
    public string Pqr { get; set; }
    public string Xyz { get; set; }
}

映射逻辑:

var serializer = new XmlSerializer(typeof(DataXml));
using var reader = XmlReader.Create("your-xml-file-path.xml");
var dataXml = (DataXml)serializer.Deserialize(reader);

var data = new Data();
foreach (var elem in dataXml.Elements)
{
    switch (elem.Id)
    {
        case "abc.pqr":
            data.Pqr = elem.Value;
            break;
        case "abc.xyz":
            data.Xyz = elem.Value;
            break;
    }
}

这两种方案都能解决默认属性映射无法正确赋值的问题,方案一适合直接绑定目标类,方案二更灵活,适合后续需要扩展更多element节点的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 07:01:57