C# XmlSerializer反序列化自闭合标签时内容溢出问题求解决
解决XmlSerializer处理自闭合XmlElement标签时的异常问题
问题背景
当使用XmlElement类型属性保留包含HTML代码的XML标签原始内容时,多数场景运行正常,但遇到自闭合标签(如<Description/>)时,序列化器会错误地将后续元素(如<Name>)纳入该XmlElement,导致后续属性无法正确反序列化。
可行解决方案
方案1:用XmlAnyElement指定匹配元素名
给XmlElement属性添加[XmlAnyElement("Description")]特性,明确限定序列化器仅匹配名为Description的元素,避免贪婪匹配:
[Serializable] public class Root { [XmlAnyElement("Description")] public XmlElement Description { get; set; } public string Name { get; set; } }
修改后,自闭合的<Description/>会被正确识别为Description属性的空元素,Name属性也能正常读取;同时原obj2场景中,Description会返回空的XmlElement而非null,更符合预期。
方案2:自定义XML序列化逻辑
实现IXmlSerializable接口,手动控制反序列化流程,彻底规避序列化器的默认行为:
[Serializable] public class Root : IXmlSerializable { public XmlElement Description { get; set; } public string Name { get; set; } public XmlSchema GetSchema() => null; public void ReadXml(XmlReader reader) { reader.ReadStartElement("Root"); while (reader.NodeType != XmlNodeType.EndElement) { if (reader.Name == "Description") { var doc = new XmlDocument(); Description = doc.ReadNode(reader) as XmlElement; } else if (reader.Name == "Name") { Name = reader.ReadElementContentAsString(); } else { reader.Skip(); } } reader.ReadEndElement(); } public void WriteXml(XmlWriter writer) { if (Description != null) { writer.WriteRaw(Description.OuterXml); } if (!string.IsNullOrEmpty(Name)) { writer.WriteElementString("Name", Name); } } }
这种方式可以完全自定义元素的读取逻辑,不仅解决自闭合标签问题,还能根据需求调整空元素的处理方式。
方案3:预处理XML文本
反序列化前,将自闭合的目标标签替换为普通空标签,避免序列化器误判:
string xml = @"<Root><Description/><Name>Test</Name></Root>"; // 替换指定自闭合标签为普通空标签 xml = Regex.Replace(xml, @"<Description/>", @"<Description></Description>"); var serializer = new XmlSerializer(typeof(Root)); var obj3 = serializer.Deserialize(new StringReader(xml));
该方式简单直接,但需注意正则表达式的精准性,避免误替换其他无关的自闭合标签。
内容的提问来源于stack exchange,提问作者Janis E.
相关产品推荐
相关产品推荐

