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

如何调整XML属性实现重复嵌套Diary标签的反序列化?

处理嵌套重复<Diary>标签的XML反序列化问题

我在反序列化请求返回的XML结果时,遇到了多层重复的<Diary>标签问题。目前我靠修改XML格式实现了反序列化,但无法修改XML源文件让它只保留单层<Diary>标签。想问下能不能通过调整XML属性来处理反序列化,不用修改响应内容?

XML响应

<?xml version="1.0" ?>
<Root>
    <DiaryDetails>
        <Diary>
            <Diary created_user="value1" created_date="value2" long_text="value3" short_text="value4" entry_type="value5" >Value6</Diary>
        </Diary>
        <Diary>
            <Diary created_user="value7" created_date="value8" long_text="value9" short_text="value10" entry_type="value11" >Value12</Diary>
        </Diary>
    </DiaryDetails>
</Root>

类定义

[XmlRoot("DiaryDetails")]
public class Diaries : List<Diary> { }

[XmlRoot("Diary")]
public class Diary
{
    [XmlAttribute("created_user")]
    public string CreatedBy { get; set; }

    [XmlAttribute("created_date")]
    public string CreatedDate { get; set; }
    [XmlAttribute("long_text")]
    public string LongText { get; set; }

    [XmlAttribute("short_text")]
    public string ShortText { get; set; }

    [XmlAttribute("entry_type")]
    public string Type { get; set; }
}

反序列化方法

internal T DeserilaiseObject<T>(string response)
{
    XmlSerializer serializer = new XmlSerializer(typeof(T));
    T DeserilaisedObject;

    using (TextReader reader = new StringReader(response))
    {
        DeserilaisedObject = (T)serializer.Deserialize(reader);
    }
    return DeserilaisedObject;
}

当前临时解决方法

我目前用字符串替换处理这个问题:

response = response.Replace("<Diary><Diary", "<Diary").Replace("</Diary></Diary>", "</Diary>");

可行解决方案(无需修改XML响应)

可以通过调整XML序列化属性的映射关系,直接适配嵌套的<Diary>标签,以下是两种直观的实现方式:

方案一:层级类映射

新增外层容器类,让序列化器识别嵌套的标签结构:

[XmlRoot("Root")]
public class Root
{
    [XmlElement("DiaryDetails")]
    public DiaryDetails DiaryDetails { get; set; }
}

public class DiaryDetails
{
    [XmlElement("Diary")]
    public List<DiaryWrapper> DiaryWrappers { get; set; }
}

public class DiaryWrapper
{
    [XmlElement("Diary")]
    public Diary Diary { get; set; }
}

[XmlRoot("Diary")]
public class Diary
{
    [XmlAttribute("created_user")]
    public string CreatedBy { get; set; }

    [XmlAttribute("created_date")]
    public string CreatedDate { get; set; }

    [XmlAttribute("long_text")]
    public string LongText { get; set; }

    [XmlAttribute("short_text")]
    public string ShortText { get; set; }

    [XmlAttribute("entry_type")]
    public string Type { get; set; }

    [XmlText]
    public string Content { get; set; } // 新增字段接收<Diary>标签内的文本内容(如Value6)
}

反序列化时指定目标类型为Root,再提取实际的Diary列表:

var root = DeserilaiseObject<Root>(response);
var diaries = root.DiaryDetails.DiaryWrappers.Select(w => w.Diary).ToList();

方案二:使用XmlAttributeOverrides简化映射

如果不想新增过多类,可以通过XmlAttributeOverrides动态调整序列化规则,不过层级类映射的方式更直观、易维护,适合长期使用。

另外注意:原Diary类缺少接收标签内文本的属性,添加[XmlText]标记的Content字段后,才能完整获取<Diary>标签内的Value6、Value12等内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 16:35:26