如何为C#类指定不同XML元素名称进行序列化?
解决方法:动态修改XML序列化元素名称
不用修改你现有的LessonOld类特性,我们可以通过XmlSerializer的构造参数动态指定不同的XML元素名称,分两种常见场景说明:
场景1:序列化单个LessonOld对象,修改根元素名称
如果你只是要把单个LessonOld实例序列化成不同的根元素(比如把原来的<Lesson>改成<Course>),直接在实例化XmlSerializer时传入XmlRootAttribute即可:
// 假设你已经初始化了一个LessonOld实例 var myLesson = new LessonOld { Name = "Advanced C#", FirstLessonDate = DateTime.Now, DurationInMinutes = 90, Students = new List<string> { "Alice", "Bob" } }; // 指定新的根元素名称为"Course" var xmlSerializer = new XmlSerializer(typeof(LessonOld), new XmlRootAttribute("Course")); using (TextWriter writer = new StreamWriter(Path.Combine(UserSettings, "Lesson-temp.xml"))) { xmlSerializer.Serialize(writer, myLesson); }
生成的XML根元素就会是<Course>,而非原来的<Lesson>。
场景2:序列化List<LessonOld>,修改子元素/根元素名称
如果是序列化集合,你可能需要修改两个部分:
- 集合的根元素(默认是
<ArrayOfLesson>) - 每个
LessonOld实例对应的子元素(默认是<Lesson>)
这时候可以用XmlAttributeOverrides动态覆盖类的XML特性:
var lessonList = new List<LessonOld> { new LessonOld { Name = "Math", FirstLessonDate = new DateTime(2024, 1, 1), DurationInMinutes = 60, Students = new List<string> { "Charlie" } }, new LessonOld { Name = "English", FirstLessonDate = new DateTime(2024, 1, 2), DurationInMinutes = 45, Students = new List<string> { "Diana" } } }; // 创建覆盖规则:把LessonOld对应的子元素名称改成"Course" var overrides = new XmlAttributeOverrides(); var lessonAttrs = new XmlAttributes(); lessonAttrs.XmlElements.Add(new XmlElementAttribute("Course")); overrides.Add(typeof(LessonOld), lessonAttrs); // 同时指定集合的根元素为"CourseCollection" var xmlSerializer = new XmlSerializer( typeof(List<LessonOld>), new XmlRootAttribute("CourseCollection"), overrides ); using (TextWriter writer = new StreamWriter(Path.Combine(UserSettings, "Lessons-temp.xml"))) { xmlSerializer.Serialize(writer, lessonList); }
最终生成的XML结构会是:
<CourseCollection> <Course> <Name>Math</Name> <FirstLessonDate>2024-01-01T00:00:00</FirstLessonDate> <DurationInMinutes>60</DurationInMinutes> <Students> <string>Charlie</string> </Students> </Course> <Course> <Name>English</Name> <FirstLessonDate>2024-01-02T00:00:00</FirstLessonDate> <DurationInMinutes>45</DurationInMinutes> <Students> <string>Diana</string> </Students> </Course> </CourseCollection>
为什么选择动态覆盖?
这种方式适合你不想改动原有LessonOld类定义的场景(比如类属于公共库、其他业务依赖原有XML名称)。如果允许修改类,你也可以直接替换[XmlRoot(ElementName = "Lesson")]为目标名称,但动态覆盖的灵活性更高,不会影响原有代码的逻辑。
内容的提问来源于stack exchange,提问作者derekantrican
相关产品推荐
相关产品推荐

