XML-反序列化嵌套列表 C#
XML-Deserialization of a nested List C#
我正在尝试使用 XmlSerializer 反序列化一个 Xml 文件。
我的文件的一部分如下所示:
<bla>
<ListOfListOfTest>
<ListOfTest>
<Test>
</Test>
</ListOfTest>
</ListOfListOfTest>
</bla>
我尝试了不同的方法,但没有用。
我的第一次尝试是这样的:
public class bla
{
public bla()
{
ListOfListOfTest = new List<List<Test>>();
}
[...]
public List<List<Test>> ListOfListOfTest{ get; set; }
}
-> 不起作用。
第二次尝试:
public class bla
{
public bla()
{
ListOfListOfTest = new List<List<Test>>();
}
[..]
public List<List<Test>> ListOfListOfTest { get; set; }
[XmlArrayItemAttribute]
public List<List<Test>> listOfListOfTest { get { return ListOfListOfTest ; } }
}
-> 也失败了
第三次尝试:
public class bla
{
public bla()
{
ListOfListOfTest = new List<Foo>();
}
[...]
public List<Foo> ListOfListOfTest { get; set; }
}
public class Foo
{
public Foo()
{
ListOfTest = new List<Test>();
}
public List<Test> ListOfTest { get; set; }
}
-> 失败...
失败意味着 XmlSerializer
在 serializer.Deserialize()
期间没有填充 List
。
我总是得到一个 List
其中有零个元素。
我做错了什么?
感谢您的努力
是这样的吗?
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Serialization;
class Program {
static void Main() {
var xml = @"<bla>
<ListOfListOfTest>
<ListOfTest>
<Test>
</Test>
</ListOfTest>
</ListOfListOfTest>
</bla>";
var bar = (Bar)new XmlSerializer(typeof(Bar)).Deserialize(new StringReader(xml));
Console.WriteLine(bar.Lists.Sum(_ => _.Items.Count)); // 1
}
}
[XmlRoot("bla")]
public class Bar {
[XmlArray("ListOfListOfTest")]
[XmlArrayItem("ListOfTest")]
public List<Foo> Lists { get; } = new List<Foo>();
}
public class Foo {
[XmlElement("Test")]
public List<Test> Items { get; } = new List<Test>();
}
public class Test { }
实际布局取决于哪些元素可能会重复,以及您是否需要能够重现确切的组织(与只想要所有 Test
项目相比)。在上面的代码中,ListOfListOfTest
预计不会重复,但可以有任意数量的 ListOfTest
或 Test
元素。
要了解正确反序列化后 XML 的外观,请复制您的 XML:
<bla>
<ListOfListOfTest>
<ListOfTest>
<Test>
</Test>
</ListOfTest>
</ListOfListOfTest>
</bla>
在 C# 中创建一个 class。单击顶部的 "Edit",然后单击 "Paste Special",然后单击 "Paste XML As Classes",同时光标位于 class 内。 Visual Studio 将为您正确反序列化 XML 并创建必要的 classes。使用它来比较您认为需要的和实际需要的,以便自己弄清楚反序列化应该如何工作。
Visual Studio 有一个方便的选项 - 您只需复制粘贴 xml 并转到菜单 Edit > Paste Special > Paste XML As 类。 Visual Studio 将生成 类,您可以将其用于 serialize/deserialize 您的 xml。在这种特殊情况下,它将生成:
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class bla
{
private blaListOfListOfTest listOfListOfTestField;
public blaListOfListOfTest ListOfListOfTest
{
get { return this.listOfListOfTestField; }
set { this.listOfListOfTestField = value; }
}
}
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class blaListOfListOfTest
{
private blaListOfListOfTestListOfTest listOfTestField;
public blaListOfListOfTestListOfTest ListOfTest
{
get { return this.listOfTestField; }
set { this.listOfTestField = value; }
}
}
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class blaListOfListOfTestListOfTest
{
private object testField;
public object Test
{
get { return this.testField; }
set { this.testField = value; }
}
}
之后您可以进行一些调整 - 例如删除类型限定符或用自动属性替换属性(这可以通过 visual studio 扩展来完成)。几次击键后:
[Serializable]
[DesignerCategory("code")]
[XmlType(AnonymousType = true)]
[XmlRoot(Namespace = "", IsNullable = false)]
public partial class bla
{
public blaListOfListOfTest ListOfListOfTest { get; set; }
}
[Serializable]
[DesignerCategory("code")]
[XmlType(AnonymousType = true)]
public partial class blaListOfListOfTest
{
public blaListOfListOfTestListOfTest ListOfTest { get; set; }
}
[Serializable]
[DesignerCategory("code")]
[XmlType(AnonymousType = true)]
public partial class blaListOfListOfTestListOfTest
{
public object Test { get; set; }
}
反序列化看起来像:
var serializer = new XmlSerializer(typeof(bla));
var blaObj = serializer.Deserialize(new StringReader(xmlString));
我正在尝试使用 XmlSerializer 反序列化一个 Xml 文件。 我的文件的一部分如下所示:
<bla>
<ListOfListOfTest>
<ListOfTest>
<Test>
</Test>
</ListOfTest>
</ListOfListOfTest>
</bla>
我尝试了不同的方法,但没有用。
我的第一次尝试是这样的:
public class bla
{
public bla()
{
ListOfListOfTest = new List<List<Test>>();
}
[...]
public List<List<Test>> ListOfListOfTest{ get; set; }
}
-> 不起作用。
第二次尝试:
public class bla
{
public bla()
{
ListOfListOfTest = new List<List<Test>>();
}
[..]
public List<List<Test>> ListOfListOfTest { get; set; }
[XmlArrayItemAttribute]
public List<List<Test>> listOfListOfTest { get { return ListOfListOfTest ; } }
}
-> 也失败了
第三次尝试:
public class bla
{
public bla()
{
ListOfListOfTest = new List<Foo>();
}
[...]
public List<Foo> ListOfListOfTest { get; set; }
}
public class Foo
{
public Foo()
{
ListOfTest = new List<Test>();
}
public List<Test> ListOfTest { get; set; }
}
-> 失败...
失败意味着 XmlSerializer
在 serializer.Deserialize()
期间没有填充 List
。
我总是得到一个 List
其中有零个元素。
我做错了什么?
感谢您的努力
是这样的吗?
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Serialization;
class Program {
static void Main() {
var xml = @"<bla>
<ListOfListOfTest>
<ListOfTest>
<Test>
</Test>
</ListOfTest>
</ListOfListOfTest>
</bla>";
var bar = (Bar)new XmlSerializer(typeof(Bar)).Deserialize(new StringReader(xml));
Console.WriteLine(bar.Lists.Sum(_ => _.Items.Count)); // 1
}
}
[XmlRoot("bla")]
public class Bar {
[XmlArray("ListOfListOfTest")]
[XmlArrayItem("ListOfTest")]
public List<Foo> Lists { get; } = new List<Foo>();
}
public class Foo {
[XmlElement("Test")]
public List<Test> Items { get; } = new List<Test>();
}
public class Test { }
实际布局取决于哪些元素可能会重复,以及您是否需要能够重现确切的组织(与只想要所有 Test
项目相比)。在上面的代码中,ListOfListOfTest
预计不会重复,但可以有任意数量的 ListOfTest
或 Test
元素。
要了解正确反序列化后 XML 的外观,请复制您的 XML:
<bla>
<ListOfListOfTest>
<ListOfTest>
<Test>
</Test>
</ListOfTest>
</ListOfListOfTest>
</bla>
在 C# 中创建一个 class。单击顶部的 "Edit",然后单击 "Paste Special",然后单击 "Paste XML As Classes",同时光标位于 class 内。 Visual Studio 将为您正确反序列化 XML 并创建必要的 classes。使用它来比较您认为需要的和实际需要的,以便自己弄清楚反序列化应该如何工作。
Visual Studio 有一个方便的选项 - 您只需复制粘贴 xml 并转到菜单 Edit > Paste Special > Paste XML As 类。 Visual Studio 将生成 类,您可以将其用于 serialize/deserialize 您的 xml。在这种特殊情况下,它将生成:
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class bla
{
private blaListOfListOfTest listOfListOfTestField;
public blaListOfListOfTest ListOfListOfTest
{
get { return this.listOfListOfTestField; }
set { this.listOfListOfTestField = value; }
}
}
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class blaListOfListOfTest
{
private blaListOfListOfTestListOfTest listOfTestField;
public blaListOfListOfTestListOfTest ListOfTest
{
get { return this.listOfTestField; }
set { this.listOfTestField = value; }
}
}
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class blaListOfListOfTestListOfTest
{
private object testField;
public object Test
{
get { return this.testField; }
set { this.testField = value; }
}
}
之后您可以进行一些调整 - 例如删除类型限定符或用自动属性替换属性(这可以通过 visual studio 扩展来完成)。几次击键后:
[Serializable]
[DesignerCategory("code")]
[XmlType(AnonymousType = true)]
[XmlRoot(Namespace = "", IsNullable = false)]
public partial class bla
{
public blaListOfListOfTest ListOfListOfTest { get; set; }
}
[Serializable]
[DesignerCategory("code")]
[XmlType(AnonymousType = true)]
public partial class blaListOfListOfTest
{
public blaListOfListOfTestListOfTest ListOfTest { get; set; }
}
[Serializable]
[DesignerCategory("code")]
[XmlType(AnonymousType = true)]
public partial class blaListOfListOfTestListOfTest
{
public object Test { get; set; }
}
反序列化看起来像:
var serializer = new XmlSerializer(typeof(bla));
var blaObj = serializer.Deserialize(new StringReader(xmlString));