使用 XmlSerializer 重命名平面 xml 数组中的数组项

Posted

技术标签:

【中文标题】使用 XmlSerializer 重命名平面 xml 数组中的数组项【英文标题】:Renaming array items in a flat xml array using an XmlSerializer 【发布时间】:2011-05-24 00:59:59 【问题描述】:

我有一个格式如下的 XML 文件:

<?xml version="1.0" encoding="UTF-8"?>
<Items>
    <Item Property1="A" Property2="B" />
    <Item Property1="C" Property2="D" />
</Items>

我需要使用 XmlSerializer 将 &lt;Item&gt; 元素作为 MyClass 类的对象读取。

public class MyCLass

    [XmlAttribute]
    public string Property1  get; set; 

    [XmlAttribute]
    public string Property2  get; set; 

目前,我有以下代码来读取文件:

XmlSerializer serializer =
    new XmlSerializer(typeof(MyClass[]), new XmlRootAttribute(@"Items"));

MyClass[] list = (MyClass[])serializer.Deserialize(...);

由于元素名&lt;Item&gt;与类名MyCLass不同,所以数组中的元素根本没有反序列化。如果我将MyClass 重命名为Item,上面的代码可以工作,但不幸的是,我不允许更改 XML 文件或类名。

如何映射两者以便正确读取文件?

提前致谢!

【问题讨论】:

【参考方案1】:

就我个人而言,我会手动进行序列化和反序列化 - 我发现以这种方式获得所需的任何灵活性比花很长时间弄乱内置序列化并忍受它施加的各种限制更容易。 LINQ to XML 使它非常简单。例如,在这种情况下:

XDocument doc = XDocument.Load("test.xml");
// You could use an array if you really wanted, of course.
List<MyClass> list = doc.Root
                        .Elements("Item")
                        .Select(x => new MyClass 
                            Property1 = (string) x.Attribute("Property1"),
                            Property2 = (string) x.Attribute("Property2"),
                         )
                        .ToList();

诚然,如果您需要序列化具有复杂关系的对象(两个对象指代同一个子对象或其他任何东西),这会变得很麻烦,但我过去已经取得了很大的成功。

【讨论】:

感谢您的提示!就我而言,实际的 MyClass 结构非常复杂,具有嵌套的层次结构 - 所以这种方法可能会有点复杂...... @xmlWiz:如果您遵循每个类都知道如何反序列化和序列化自身的模式,我发现它还不错 - 并且易于单元测试。但如果你有共享参考等,它确实会变得复杂。【参考方案2】:

使用包含数组的包装类,这将允许您应用XmlElement 属性:

public class MyClassList

    [XmlElement("Item")]
    public MyClass[] Items  get; set; 


var items = new[]

    new MyClass  Property1 = "A", Property2 = "B" ,
    new MyClass  Property1 = "C", Property2 = "D" ,
;
var list = new MyClassList  Items = items ;

using (var writer = new StringWriter())

    var xs = new XmlSerializer(typeof(MyClassList), new XmlRootAttribute("Items"));
    xs.Serialize(writer, list);
    writer.ToString().Dump();

【讨论】:

我不太确定它为什么会起作用 :-) 我在 XmlArrayItem 和 XmlAttributeOverrides 之后跑来跑去。再次感谢!

以上是关于使用 XmlSerializer 重命名平面 xml 数组中的数组项的主要内容,如果未能解决你的问题,请参考以下文章

使用不带属性的 DataContractSerializer 或 XmlSerializer 删除所有命名空间

XmlSerializer c++ 使用多个命名空间反序列化

c# XmlSerializer 反序列化器缺少默认命名空间

我可以让 XmlSerializer 在反序列化时忽略命名空间吗?

C# XmlSerializer 用不同的命名空间序列化同一个类

平面最近点对