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

非泛型ArrayList序列化输出ArrayOfAnyType,如何生成目标XML结构?

问题描述

序列化非泛型ArrayList时遇到XML结构不符合预期的问题,必须使用非泛型ArrayList,添加[XmlArray("LineDetails")]后代码可运行,但输出的XML嵌套了多余的anyType节点,无法生成目标结构。XML层级要求为Document > Header > LineCollection > LineDetails,其中LineDetails是动态数量的节点。

相关代码

[XmlType(TypeName = "LineCollection")]
public class LineCollection
{
    public String LineCount{ get; set; }          
    //  [XmlElement(ElementName = "LineDetails")]
    [XmlArray("LineDetails")]
    public ArrayList LineDetails{ get; set; } 
}
public class LineDetails: ArrayList 
{
    public String LineNum{ get; set; } 
    public String ItemId{ get; set; } 
    public String ItemName{ get; set; } 
    //... only strings
}

public class Utf8StringWriter : StringWriter
{
    public override Encoding Encoding => new UTF8Encoding(false);
}

public string Serialize()
{
    // var xmlserializer = new XmlSerializer(this.GetType());
    var xmlserializer = new XmlSerializer(this.GetType(), new Type[] { typeof(LineDetails) });
    var Utf8StringWriter = new Utf8StringWriter();
    var xns = new XmlSerializerNamespaces();
    xns.Add(string.Empty, string.Empty);
    using (var writer = XmlWriter.Create(Utf8StringWriter))
    {
        xmlserializer.Serialize(writer, this, xns);
        return Utf8StringWriter.ToString();
    }
}

当前错误输出

<LineColletion>
    <LineDetails>
        <anyType xmlns:p5="http://www.w3.org/2001/XMLSchema-instance" p5:type="LineDetails">
            <LineNum>1</LineNum>
            <ItemId>Item_2321</ItemId>
            <ItemName>TheItemName</ItemName>
        </anyType>
        <anyType xmlns:p5="http://www.w3.org/2001/XMLSchema-instance" p5:type="LineDetails">
            <LineNum>2</LineNum>
            <ItemId>Item_2321</ItemId>
            <ItemName>TheItemName</ItemName>
        </anyType>
    </LineDetails>
</LineColletion>

期望输出

<LineColletion>
    <LineDetails>
        <LineNum>1</LineNum>
        <ItemId>Item_2321</ItemId>
        <ItemName>TheItemName</ItemName>
    </LineDetails>
    <LineDetails>
        <LineNum>2</LineNum>
        <ItemId>Item_232100000</ItemId>
        <ItemName>TheItemName0</ItemName>
    </LineDetails>
    <LineDetails>
        <LineNum>3</LineNum>
        <ItemId>Item_23217777</ItemId>
        <ItemName>TheItemName7</ItemName>
    </LineDetails>
</LineColletion>
解决方法

核心问题有两个:

  1. LineDetails类不应继承ArrayList:它只是单个行数据的实体类,不需要继承集合类型,否则序列化时会被识别为集合而非普通对象。
  2. LineCollection中的LineDetails属性需用[XmlElement]替代[XmlArray]:[XmlArray]会生成包裹数组的父节点,而我们需要多个LineDetails节点直接作为LineCollection的子节点。

修改后的代码如下:

[XmlType(TypeName = "LineCollection")]
public class LineCollection
{
    public String LineCount { get; set; }

    // 使用XmlElement标记,指定每个集合元素的节点名称
    [XmlElement(ElementName = "LineDetails")]
    public ArrayList LineDetails { get; set; }
}

// 移除ArrayList继承,改为普通实体类
public class LineDetails
{
    public String LineNum { get; set; }
    public String ItemId { get; set; }
    public String ItemName { get; set; }
    //... 其他字符串字段
}

// 以下代码保持不变
public class Utf8StringWriter : StringWriter
{
    public override Encoding Encoding => new UTF8Encoding(false);
}

public string Serialize()
{
    var xmlserializer = new XmlSerializer(this.GetType(), new Type[] { typeof(LineDetails) });
    var utf8StringWriter = new Utf8StringWriter();
    var xns = new XmlSerializerNamespaces();
    xns.Add(string.Empty, string.Empty);
    using (var writer = XmlWriter.Create(utf8StringWriter))
    {
        xmlserializer.Serialize(writer, this, xns);
        return utf8StringWriter.ToString();
    }
}

修改说明:

  • 去掉LineDetails的ArrayList继承后,XmlSerializer会将其识别为普通可序列化对象,不再生成anyType节点。
  • [XmlElement("LineDetails")]告知XmlSerializer:ArrayList中的每个元素都序列化为<LineDetails>节点,直接作为LineCollection的子节点,避免了不必要的嵌套。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 05:35:42