在 C# 中使用 XmlSerializer
进行 XML 序列化时,默认会自动添加以下两个命名空间声明:
xml
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
这些命名空间是为了支持 XML Schema 实例(XSI)和 XML Schema 定义(XSD)的验证。但在某些场景下,你可能希望 去掉这些命名空间声明,以满足特定的格式要求或与外部系统兼容。
✅ 解决方案:删除 xmlns:xsd
和 xmlns:xsi
方法一:使用 XmlAttributeOverrides
和 XmlSerializerNamespaces
这是最推荐、最灵活的方式,适用于大多数 XML 序列化场景。
✅ 示例代码
csharp
using System;
using System.IO;
using System.Xml.Serialization;
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
class Program
{
static void Main()
{
Person person = new Person { Name = "Alice", Age = 25 };
// 创建 XmlAttributeOverrides,覆盖默认的命名空间
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
XmlAttributes attributes = new XmlAttributes();
// 设置 XmlRootAttribute 并指定命名空间为空
XmlRootAttribute root = new XmlRootAttribute("Person");
root.Namespace = ""; // 设置为空字符串
attributes.XmlRoot = root;
overrides.Add(typeof(Person), attributes);
// 创建 XmlSerializer,并使用空的命名空间集合
XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
namespaces.Add(string.Empty, string.Empty); // 忽略默认命名空间
XmlSerializer serializer = new XmlSerializer(typeof(Person), overrides);
using (StringWriter writer = new StringWriter())
{
serializer.Serialize(writer, person, namespaces);
Console.WriteLine(writer.ToString());
}
}
}
输出结果
xml
<Person>
<Name>Alice</Name>
<Age>25</Age>
</Person>
方法二:使用 XmlTextWriter
手动控制输出格式(可选)
如果你需要更细粒度的控制(例如删除特定属性),可以使用 XmlTextWriter
并在写入时忽略命名空间。
示例代码(使用 XmlTextWriter)
csharp
using System;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
class Program
{
static void Main()
{
Person person = new Person { Name = "Alice", Age = 25 };
XmlSerializer serializer = new XmlSerializer(typeof(Person));
using (StringWriter stringWriter = new StringWriter())
using (XmlTextWriter xmlWriter = new XmlTextWriter(stringWriter))
{
xmlWriter.Formatting = Formatting.Indented;
// 禁用命名空间处理
XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
namespaces.Add(string.Empty, string.Empty);
serializer.Serialize(xmlWriter, person, namespaces);
Console.WriteLine(stringWriter.ToString());
}
}
}
📌 注意事项
项目 | 说明 |
---|---|
命名空间是否必须 | 如果你的 XML 需要被外部系统验证或解析为特定的 Schema,删除 xsd 和 xsi 可能会导致兼容性问题。 |
性能影响 | 使用 XmlAttributeOverrides 和 XmlSerializerNamespaces 对性能影响较小,推荐使用。 |
是否影响反序列化 | 如果你使用相同的类结构进行反序列化,即使没有命名空间声明,XmlSerializer 也能正确识别。 |
是否适用于嵌套类/集合类 | 是的,上述方法适用于包含嵌套类、集合类等复杂结构的序列化。 |
🧩 高级用法:序列化集合类并去除命名空间
csharp
[XmlRoot("People")]
public class People
{
[XmlElement("Person")]
public List<Person> Persons { get; set; }
}
// 序列化时使用相同的方法,添加 XmlAttributeOverrides
✅ 总结
方法 | 说明 | 推荐程度 |
---|---|---|
XmlAttributeOverrides + XmlSerializerNamespaces | 推荐方式,控制命名空间最灵活 | ⭐⭐⭐⭐⭐ |
XmlTextWriter + 手动控制 | 可选方式,适用于需要更细粒度控制的场景 | ⭐⭐⭐ |
直接修改 XML 字符串 | 不推荐,容易出错且不可靠 | ❌ |
通过上述方法,你可以轻松地 在 XML 序列化时去除 xmlns:xsd
和 xmlns:xsi
命名空间声明 。推荐使用 XmlAttributeOverrides
和 XmlSerializerNamespaces
的组合,这是最稳定、最推荐的方式,适用于大多数 XML 序列化场景,包括嵌套类、集合类等复杂结构。