C# Xml序列化问题:移除tns前缀与空xmlns属性
解决C# XmlSerializer生成指定命名空间XML的问题
问题背景
需要生成的目标XML结构如下:
<?xml version="1.0" encoding="utf-16"?> <myObject xmlns="example_namespace"> <name>John Doe</name> <details xmlns:tns="randomNamespace" xmlns="randomNamespace"> <address>123 Main St</address> </details> </myObject>
原代码序列化后会出现两种问题:要么<address>带tns前缀,要么添加Form = XmlSchemaForm.Unqualified后出现空xmlns=""属性,需要非字符串替换的解决方案。
调整类的Xml序列化属性
通过精准配置序列化特性,让元素正确继承命名空间并生成指定的命名空间声明:
[XmlRoot(Namespace = "example_namespace", ElementName = "myObject")] public class MyObject { [XmlElement("name")] public string Name { get; set; } // 指定details元素的命名空间为randomNamespace,自动生成xmlns="randomNamespace" [XmlElement("details", Namespace = "randomNamespace")] public Details Details { get; set; } } // 声明Details类的默认命名空间为randomNamespace,其子元素默认继承该命名空间 [XmlType(Namespace = "randomNamespace")] public class Details { // 设置Form为Unqualified,避免生成前缀,同时继承父类的命名空间 [XmlElement("address", Form = XmlSchemaForm.Unqualified)] public string Address { get; set; } // 显式声明xmlns:tns属性,使用xmlns的标准命名空间 [XmlAttribute(AttributeName = "tns", Namespace = "http://www.w3.org/2000/xmlns/")] public string TnsPrefix { get; set; } = "randomNamespace"; }
序列化代码示例
使用标准XmlSerializer即可生成符合要求的XML:
var myObject = new MyObject { Name = "John Doe", Details = new Details { Address = "123 Main St" } }; var serializer = new XmlSerializer(typeof(MyObject)); using var stringWriter = new StringWriter(); serializer.Serialize(stringWriter, myObject); var resultXml = stringWriter.ToString();
方案说明
- MyObject类配置:
[XmlElement("details", Namespace = "randomNamespace")]让<details>元素使用randomNamespace作为默认命名空间,自动生成xmlns="randomNamespace"属性。 - Details类配置:
[XmlType(Namespace = "randomNamespace")]指定类的默认命名空间,确保<address>继承该命名空间;[XmlElement("address", Form = XmlSchemaForm.Unqualified)]避免为<address>添加命名空间前缀。 - tns前缀声明:通过
[XmlAttribute]指定xmlns:tns属性,使用http://www.w3.org/2000/xmlns/这个标准命名空间来声明前缀与命名空间的映射。
序列化后的XML完全符合目标结构,无需任何字符串替换操作。
内容的提问来源于stack exchange,提问作者Machnov Andrey
相关产品推荐
相关产品推荐

