使用XmlSerializer实现含递增编号同名元素的XML序列化/反序列化及指定类序列化
如何用XmlSerializer实现带递增编号元素的XML序列化与反序列化
没问题,要实现你需要的这种自定义命名的XML序列化和反序列化,咱们可以通过XmlAttributeOverrides来动态配置每个数组元素的XML节点名称,完美适配Element_01、Element_02这种带两位递增编号的格式。下面是具体的实现方案:
核心原理
默认情况下,XmlSerializer处理字符串数组时,会生成嵌套的<Elements><string>...</string></Elements>结构,但我们需要每个元素对应独立的、带编号的节点。这时候就需要用XmlAttributeOverrides,为数组中的每个元素单独指定XmlElementAttribute,把节点名称设置为Element_加上两位格式的索引(从1开始计数)。
完整代码实现
1. 基础类定义
首先还是用你给出的Root类:
public class Root { public string[] Elements { get; set; } }
2. 序列化方法
写一个通用的序列化方法,处理这种带编号的节点生成:
public static string SerializeRoot(Root root) { if (root?.Elements == null) return string.Empty; // 创建属性重写配置 var overrides = new XmlAttributeOverrides(); var elementAttributes = new XmlAttributes(); // 遍历每个元素,为其指定自定义XML节点名称 for (int i = 0; i < root.Elements.Length; i++) { // 生成两位编号的节点名,比如Element_01、Element_02 string elementName = $"Element_{(i + 1):D2}"; elementAttributes.XmlElements.Add(new XmlElementAttribute(elementName)); } // 将配置应用到Root类的Elements属性上 overrides.Add(typeof(Root), nameof(Root.Elements), elementAttributes); // 使用自定义配置创建XmlSerializer var serializer = new XmlSerializer(typeof(Root), overrides); // 执行序列化 using var writer = new StringWriter(); serializer.Serialize(writer, root); return writer.ToString(); }
3. 反序列化方法
反序列化需要和序列化用相同的配置,这样才能正确识别Element_XX节点:
public static Root DeserializeRoot(string xml) { if (string.IsNullOrEmpty(xml)) return null; // 先解析XML,获取所有Element_XX节点的数量,构建对应的属性重写 var doc = new XmlDocument(); doc.LoadXml(xml); var elementNodes = doc.SelectNodes("//*[starts-with(local-name(), 'Element_')]"); if (elementNodes == null || elementNodes.Count == 0) return new Root { Elements = Array.Empty<string>() }; // 构建和序列化时一致的属性重写配置 var overrides = new XmlAttributeOverrides(); var elementAttributes = new XmlAttributes(); for (int i = 0; i < elementNodes.Count; i++) { string elementName = $"Element_{(i + 1):D2}"; elementAttributes.XmlElements.Add(new XmlElementAttribute(elementName)); } var serializer = new XmlSerializer(typeof(Root), overrides); // 执行反序列化 using var reader = new StringReader(xml); return (Root)serializer.Deserialize(reader); }
4. 测试代码
你可以用这段代码来验证效果:
var root = new Root { Elements = new[] { "1st element", "2nd element", "3rd element", "4th element" } }; // 序列化 string xml = SerializeRoot(root); Console.WriteLine(xml); // 反序列化 Root deserializedRoot = DeserializeRoot(xml); foreach (var elem in deserializedRoot.Elements) { Console.WriteLine(elem); }
输出效果
序列化后你会得到完全符合要求的XML:
<?xml version="1.0" encoding="utf-16"?> <Root> <Element_01>1st element</Element_01> <Element_02>2nd element</Element_02> <Element_03>3rd element</Element_03> <Element_04>4th element</Element_04> </Root>
(注:如果需要utf-8编码,可以把StringWriter替换成自定义的Utf8StringWriter类,或者在序列化时指定编码参数)
内容的提问来源于stack exchange,提问作者fboers
相关产品推荐
相关产品推荐

