求助: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实体
(表示换行),这样解析器会将其还原为原始换行符。修改后的Payload如下:
<Form> <Field Sql="select top(1)
Row
FROM
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
相关产品推荐
相关产品推荐

