C# XmlSerializer值为null或空字符串时不输出XML标签如何解决
XmlSerializer 空值/Null值属性不输出标签问题
目前公开资料里大部分是讲解如何隐藏XML序列化生成的标签,很少有资料说明属性值为null或空字符串时,如何让XmlSerializer正常输出对应标签。
已尝试的无效配置:
- 为属性添加
XmlElement特性,设置IsNullable = true - 为属性添加
XmlElement特性,设置IsNullable = false
两种配置下MyProperty对应的XML标签始终不生成,仅当属性持有非空值时才会输出对应标签。
复现代码
以下是模拟真实业务场景的示例代码(实际业务中序列化结果会作为现有XmlDocument的一部分存储,逻辑为加载原有XML文档、定位待插入节点位置后保存整份文档,完整业务代码体量较大,不便全部展示):
public class MyClass { public string MyProperty { get; set; } } var myClass = new MyClass(); var xmlSerializer = new XmlSerializer(myClass.GetType()); var xmlSerializerNamespaces = new XmlSerializerNamespaces(); xmlSerializerNamespaces.Add("", ""); var xmlWriterSettings = new XmlWriterSettings { Indent = true, OmitXmlDeclaration = true, Async = true }; using var stringWriter = new StringWriter(); using (var xmlWriter = XmlWriter.Create(stringWriter, xmlWriterSettings)) { xmlSerializer.Serialize(xmlWriter, myClass, xmlSerializerNamespaces); await xmlWriter.FlushAsync(); xmlWriter.Close(); xmlWriter.Dispose(); } await stringWriter.FlushAsync(); stringWriter.Close(); await stringWriter.DisposeAsync(); var xDocument = XDocument.Parse(stringWriter.ToString()); xDocument.Descendants().Where(e => string.IsNullOrEmpty(e.Value)).Remove(); xDocument.Save(myClass);
问题根因
IsNullable配置不生效和XmlSerializer本身无关,问题出在序列化完成后自行添加的节点处理逻辑:
- 配置
[XmlElement(IsNullable = true)]时,属性为null的场景下XmlSerializer本来就会正常输出<MyProperty xsi:nil="true" />标签 - 如果给属性赋值为空字符串,不做任何特性配置,序列化也会输出
<MyProperty />或<MyProperty></MyProperty>空标签 - 序列化后执行的
xDocument.Descendants().Where(e => string.IsNullOrEmpty(e.Value)).Remove()逻辑,会把所有值为空的节点(包括序列化生成的MyProperty空标签)直接删除,自然最终输出里看不到对应标签。
修复方案
两种方案按需选择:
- 需要输出null对应的
xsi:nil标记标签- 给对应属性添加特性:
[XmlElement(IsNullable = true)] - 调整后续空节点删除逻辑,不要把需要保留的空节点(比如MyProperty)纳入删除范围
- 给对应属性添加特性:
- 需要输出空内容标签(无xsi命名空间标记)
- 给属性设置空字符串默认值,避免属性为null:
public string MyProperty { get; set; } = string.Empty; - 同样调整后置的空节点清理逻辑,过滤掉需要保留的空标签,不要全量删除所有空值节点。
- 给属性设置空字符串默认值,避免属性为null:
补充:XmlSerializer默认规则确实是不输出值为null的引用类型属性对应的标签,
IsNullable = true就是官方提供的null值输出标签的配置,之前配置不生效完全是后置节点删除逻辑导致的,和序列化配置本身没有关系。
内容的提问来源于stack exchange,提问作者Chris Ward
相关产品推荐
相关产品推荐

