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

XmlSerializer处理非格式化XML时跳过元素的代码调整咨询

紧凑格式XML下XmlSerializer跳过元素的解决办法

问题现象

当XML为紧凑格式时:

<ArrayOfColumn><Column><COLUMN_NAME>SomeName1</COLUMN_NAME></Column><Column><COLUMN_NAME>SomeName2</COLUMN_NAME></Column></ArrayOfColumn>

以下C#代码会跳过第二个Column元素(若有更多元素则每隔一个跳过):

using (var xmlReader = XmlReader.Create(fileStream))
{
    var serializer = new XmlSerializer(typeof(MyColumnClass), new XmlRootAttribute("Column"));
    var myColumnList = new List<MyColumnClass>();
    while (xmlReader.ReadToFollowing("Column"))
    {
        myColumnList.Add((MyColumnClass)serializer.Deserialize(xmlReader));
    }
    // 后续代码
}

而当XML为格式化(带缩进)格式时,代码运行完全正常:

<ArrayOfColumn>
    <Column>
        <COLUMN_NAME>SomeName1</COLUMN_NAME>
    </Column>
    <Column>
        <COLUMN_NAME>SomeName2</COLUMN_NAME>
    </Column>
</ArrayOfColumn>

问题原因

问题出在XmlReader.ReadToFollowing和XmlSerializer.Deserialize的配合逻辑上:

  • 调用ReadToFollowing("Column")找到目标元素后,Deserialize会读取整个Column元素(包括结束标签),此时XmlReader的位置停在</Column>之后。
  • 紧凑格式XML中,下一个<Column>紧跟在</Column>之后,ReadToFollowing会从当前位置扫描,阅读器会误判节点边界,导致跳过紧邻的<Column>元素。
  • 格式化XML的换行和缩进让阅读器能正确识别节点边界,因此不会出现跳过问题。

解决办法

方法一:定义集合根类直接反序列化(推荐)

定义对应ArrayOfColumn的类,直接反序列化整个XML结构,无需手动遍历:

// 定义集合根类
[XmlRoot("ArrayOfColumn")]
public class ArrayOfColumn
{
    [XmlElement("Column")]
    public List<MyColumnClass> Columns { get; set; } = new List<MyColumnClass>();
}

// 读取代码
using (var xmlReader = XmlReader.Create(fileStream))
{
    var serializer = new XmlSerializer(typeof(ArrayOfColumn));
    var arrayOfColumn = (ArrayOfColumn)serializer.Deserialize(xmlReader);
    var myColumnList = arrayOfColumn.Columns;
    // 后续处理逻辑
}

这种方式最可靠,XmlSerializer会自动处理所有Column元素,兼容两种XML格式。

方法二:改用XmlReader.Read()遍历节点

如果不想新增类,可以调整遍历方式,手动检查节点:

using (var xmlReader = XmlReader.Create(fileStream))
{
    var serializer = new XmlSerializer(typeof(MyColumnClass), new XmlRootAttribute("Column"));
    var myColumnList = new List<MyColumnClass>();
    
    while (xmlReader.Read())
    {
        // 仅当遇到名为Column的元素节点时反序列化
        if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "Column")
        {
            myColumnList.Add((MyColumnClass)serializer.Deserialize(xmlReader));
        }
    }
    // 后续处理逻辑
}

这种方式通过逐节点遍历,确保不会错过任何Column元素,适配两种XML格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 03:20:54