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

XmlSerializer序列化List<T>节点嵌套问题及解决方案咨询

问题描述

使用XmlSerializer将C#类对象导出为XML时,序列化List<T>属性出现同名节点嵌套的问题。

测试类结构如下:

public class PmtInf
{
  public string PmtInfId = "PAYMENT REFERENCE";//Referencia de pago
  public string PmtMtd = "TRF";
  public PmtTpInf PmtTpInf = new PmtTpInf();
  public string ReqdExctnDt = "2020-06-24";//Fecha de pago
  public Dbtr Dbtr = new Dbtr();
  public InitgPty DbtrAcct = new InitgPty();
  // 问题属性
  public List<CdtTrfTxInf> CdtTrfTxInf = new List<CdtTrfTxInf>() { new CdtTrfTxInf(), new CdtTrfTxInf() };
}

public class CdtTrfTxInf
{
  public PmtId PmtId = new PmtId();
  public Amt Amt = new Amt();
  public CdtrAgt CdtrAgt = new CdtrAgt();
  public Dbtr Cdtr = new Dbtr();
  public InitgPty CdtrAcct = new InitgPty();
}

序列化代码:

var XML = new System.Xml.Serialization.XmlSerializer(Objeto.GetType());

var Path = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "//XMLExport.xml"; // 原代码缺少+号,需修正
FileStream file = File.Create(Path);

XML.Serialize(file, Objeto);
file.Close();

当前生成的XML中,<CdtTrfTxInf>节点出现嵌套:

<PmtInf>
 <PmtInfId>PAYMENT REFERENCE</PmtInfId>
 <PmtMtd>TRF</PmtMtd>
 <PmtTpInf>
 </PmtTpInf>
 <ReqdExctnDt>2020-06-24</ReqdExctnDt>
 <Dbtr>
 </Dbtr>
 <DbtrAcct>
 </DbtrAcct>

 <!-- 问题:外层<CdtTrfTxInf>包裹了子节点 -->
 <CdtTrfTxInf>
  <CdtTrfTxInf>
     more....
  </CdtTrfTxInf>
  <CdtTrfTxInf>
     more....
  </CdtTrfTxInf>
 </CdtTrfTxInf>

</PmtInf>

期望的XML结构是在<PmtInf>下直接生成多个同级<CdtTrfTxInf>节点:

<PmtInf>
 <PmtInfId>PAYMENT REFERENCE</PmtInfId>
 <PmtMtd>TRF</PmtMtd>
 <PmtTpInf>
 </PmtTpInf>
 <ReqdExctnDt>2020-06-24</ReqdExctnDt>
 <Dbtr>
 </Dbtr>
 <DbtrAcct>
 </DbtrAcct>

 <CdtTrfTxInf>
    more....
 </CdtTrfTxInf>
 <CdtTrfTxInf>
    more....
 </CdtTrfTxInf>

</PmtInf>
解决方案

问题根源是XmlSerializer默认会为List<T>类型生成一个与属性/字段同名的外层包裹节点,再在内部生成与元素类型同名的子节点。由于你的List字段名和元素类型名都是CdtTrfTxInf,就出现了嵌套的同名节点。

只需两步修改即可解决:

  1. 将公共字段改为属性(XmlSerializer更推荐使用属性进行序列化,特性也更易管控)
  2. 为List属性添加[XmlElement]特性,指定每个元素的节点名称,让序列化器直接输出同级节点,不生成外层包裹节点

修改后的PmtInf类代码:

using System.Xml.Serialization; // 需引用此命名空间

public class PmtInf
{
  public string PmtInfId { get; set; } = "PAYMENT REFERENCE";//Referencia de pago
  public string PmtMtd { get; set; } = "TRF";
  public PmtTpInf PmtTpInf { get; set; } = new PmtTpInf();
  public string ReqdExctnDt { get; set; } = "2020-06-24";//Fecha de pago
  public Dbtr Dbtr { get; set; } = new Dbtr();
  public InitgPty DbtrAcct { get; set; } = new InitgPty();
  
  // 添加XmlElement特性,指定节点名,去掉外层包裹
  [XmlElement("CdtTrfTxInf")]
  public List<CdtTrfTxInf> CdtTrfTxInf { get; set; } = new List<CdtTrfTxInf>() { new CdtTrfTxInf(), new CdtTrfTxInf() };
}

同时修正序列化代码中的路径拼接错误(原代码缺少+号):

var Path = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "//XMLExport.xml";

这样修改后,序列化生成的XML就会直接在<PmtInf>节点下生成多个同级的<CdtTrfTxInf>节点,符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 14:18:09