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

求助:XML反序列化后为何丢失换行符

问题:XML反序列化时属性值中的换行符丢失

我从浏览器发送以下XML格式的Payload:

<Form>
<Field Sql="select top(1) 
Row
FROM 
Table">
</Field>
</Form>

注意:Sql属性值包含换行符,Row、FROM、Table分别位于新行。

我将该XML字符串传入以下方法进行反序列化:

调用代码

XmlSerializationUtility.FromXml<MyPayload>(xml, "Form")

FromXml方法实现

public static T FromXml<T>(string xml, string root)
{
    XmlSerializer xmlSer = GetXMLSerializer(typeof(T), new XmlRootAttribute(root));
    var stringReader = new StringReader(xml);
    T result = (T)xmlSer.Deserialize(stringReader);

    // 输出或检查反序列化后的值
    Console.WriteLine("Deserialized value: " + result?.ToString());

    // 返回反序列化结果
    return result;
}

GetXMLSerializer方法实现

private static XmlSerializer GetXMLSerializer(Type type, XmlRootAttribute root)
{
    string key = string.Format(CultureInfo.InvariantCulture, "CachedXmlSerializer:{0}:{1}", type, root.ElementName);

    bool isCached = _serializers.TryGetValue(key, out XmlSerializer ser);

    if (!isCached)
    {
        ser = new XmlSerializer(type, root);
        _serializers.Add(key, ser);
    }

    return ser;
}

执行FromXml方法后,发现Sql属性值中的所有换行符都丢失了,结果变成了:select top(1) Row FROM Table。


原因分析

这是因为XML规范对属性值中的空白字符有默认处理规则:

  • XML解析器会自动将属性值中的换行符、回车符、制表符等空白字符统一替换为空格,除非这些空白字符被明确标记为需要保留。
  • .NET的XmlSerializer严格遵循XML规范,在反序列化属性值时,会默认执行这个空白替换逻辑,导致原始的换行符被替换成空格。

解决办法

如果要保留属性值中的换行符,有两种可行方案:

方案1:发送XML时转义换行符

将Payload中的换行符转义为XML实体&#xA;(表示换行),这样解析器会将其还原为原始换行符。修改后的Payload如下:

<Form>
<Field Sql="select top(1)&#xA;Row&#xA;FROM&#xA;Table">
</Field>
</Form>

方案2:反序列化时配置保留空白

修改FromXml方法,使用XmlReaderSettings关闭空白忽略,让解析器保留原始空白字符:

public static T FromXml<T>(string xml, string root)
{
    XmlSerializer xmlSer = GetXMLSerializer(typeof(T), new XmlRootAttribute(root));
    var settings = new XmlReaderSettings { IgnoreWhitespace = false };
    using (var stringReader = new StringReader(xml))
    using (var xmlReader = XmlReader.Create(stringReader, settings))
    {
        T result = (T)xmlSer.Deserialize(xmlReader);
        Console.WriteLine("Deserialized value: " + result?.ToString());
        return result;
    }
}

注意:这种方式仅当浏览器发送的XML中确实包含原始换行符时有效,如果浏览器在发送前已经自动处理了空白,还是需要优先使用方案1的实体转义方式。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 06:25:13