C#怎么在序列化时改变XML元素名称 [XmlElement("NewName")]

最直接标准的方式是用[XmlElement("NewName")]特性标注公共属性。该特性必须应用于具有get/set访问器的public property,可自定义XML元素名,区分大小写,重复名称会抛异常。

在 C# 中,使用 XmlSerializer 序列化对象为 XML 时,想让某个属性生成的 XML 元素名不是属性名本身,而是自定义名称,最直接、标准的方式就是用 [XmlElement("NewName")] 特性(Attribute)标注该属性。

确保特性正确应用在属性上

这个特性必须写在**公共属性(public property)**上,不能写在字段(field)上(除非你显式序列化字段,但不推荐)。它只对属性生效,且要求属性有 get/set 访问器(至少要有 get)。

  • ✅ 正确写法:
[XmlElement("ProductName")]
public string Name { get; set; }
  • ❌ 错误写法(写在私有字段上,默认不被 XmlSerializer 处理):
private string _name;
[XmlElement("ProductName")] // 这个会被忽略
public string Name => _name;

注意命名冲突与默认行为

如果不加 [XmlElement],XML 元素名默认等于属性名(PascalCase 形式)。加上后,会完全替换为指定名称。如果多个属性用了相同 [XmlElement("SameName")],XmlSerializer 会抛出异常(重复元素名),除非配合 [XmlArray][XmlChoiceIdentifier] 等做更复杂控制。

  • 属性名是 Price → 默认 XML 是 99.9
  • 加了 [XmlElement("cost")] → 变成 99.9(区分大小写)

其他常见配合用法

实际中常和以下特性一起用,解决更具体需求:

  • [XmlElement(ElementName = "Title", IsNullable = true)]:显式指定名称 + 允许 null 值输出为 xsi:nil="true"
  • [XmlElement(typeof(string), ElementName = "Value")]:用于泛型或 object 类型,明确序列化类型和元素名
  • [XmlRoot("ProductList")]:作用于类上,控制整个 XML 的根元素名
  • [XmlAttribute("id")]:如果想让属性变成 XML 属性而非子元素,用这个代替 XmlElement

验证是否生效的小技巧

写个简单测试,序列化后直接看输出字符串,比查文档更快:

var product = new Product { Name = "Laptop" };
var serializer = new XmlSerializer(typeof(Product));
using var writer = new StringWriter();
serializer.Serialize(writer, product);
Console.WriteLine(writer.ToString());

输出中应看到 Laptop 而非 Laptop

基本上就这些 —— [XmlElement("xxx")] 是最常用也最可靠的改名方式,只要用对位置、注意作用目标,基本不会出错。