如何序列化List <List >?

框架是c#.net 4.6.2

我正在从XML代码生成自动XML类

当我自动生成时,它会自动转换为Array[][]

但我想用它作为List<List>

我确信我从Array到List的对话会导致一些序列化错误。 我认为这是关于获取和设置function。 所以我需要你的帮助来解决这个问题

这里是我编辑>粘贴特殊>粘贴XML作为类时自动生成的代码片段

  ///  [System.SerializableAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] public partial class OxFordDefinition_perGroup { private string _GroupDescField; private string _GroupSenseField; private string _GroupGrammerField; private OxFordDefinition_perGroup_perMainExample_perSubExample[][] _perMainExampleField; ///  public string _GroupDesc { get { return this._GroupDescField; } set { this._GroupDescField = value; } } ///  public string _GroupSense { get { return this._GroupSenseField; } set { this._GroupSenseField = value; } } ///  public string _GroupGrammer { get { return this._GroupGrammerField; } set { this._GroupGrammerField = value; } } ///  [System.Xml.Serialization.XmlArrayItemAttribute("_perSubExample", typeof(OxFordDefinition_perGroup_perMainExample_perSubExample), IsNullable = false)] public OxFordDefinition_perGroup_perMainExample_perSubExample[][] _perMainExample { get { return this._perMainExampleField; } set { this._perMainExampleField = value; } } } 

但是我想使用List<List>而不是数组

所以我就像下面这样

  ///  [System.SerializableAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] public partial class OxFordDefinition_perGroup { private string _GroupDescField; private string _GroupSenseField; private string _GroupGrammerField; private List<List> _perMainExampleField; ///  public string _GroupDesc { get { return this._GroupDescField; } set { this._GroupDescField = value; } } ///  public string _GroupSense { get { return this._GroupSenseField; } set { this._GroupSenseField = value; } } ///  public string _GroupGrammer { get { return this._GroupGrammerField; } set { this._GroupGrammerField = value; } } ///  [System.Xml.Serialization.XmlArrayItemAttribute("_perSubExample", typeof(OxFordDefinition_perGroup_perMainExample_perSubExample), IsNullable = false)] public List<List> _perMainExample { get { return this._perMainExampleField; } set { this._perMainExampleField = value; } } } 

但这次当我尝试序列化时,它会给出序列化错误

  public static string SerializeXML(this T toSerialize) { XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); StringWriter textWriter = new StringWriter(); xmlSerializer.Serialize(textWriter, toSerialize); return textWriter.ToString(); } 

这里是XML类的完整代码

http://pastebin.com/y5B8ENM3

这是它给出的错误

在此处输入图像描述

实际上,您的原始版本和修改后的OxFordDefinition_perGroup都不能成功序列化。 问题是XmlArrayItem.Type的值,它是构造函数的第二个参数:

 [System.Xml.Serialization.XmlArrayItemAttribute("_perSubExample", typeof(OxFordDefinition_perGroup_perMainExample_perSubExample), IsNullable = false)] public OxFordDefinition_perGroup_perMainExample_perSubExample[][] { get; set; } 

根据文件

使用Type属性为公共字段或公共读/写属性值指定重写类型。

如果字段或属性返回Object类型的数组,则将XmlArrayItemAttribute多个实例应用于字段或属性。 对于每个实例,将Type属性设置为可以插入到数组中的对象类型。

typeof(OxFordDefinition_perGroup_perMainExample_perSubExample)指示最外面集合中的项目将是typeof(OxFordDefinition_perGroup_perMainExample_perSubExample)类型typeof(OxFordDefinition_perGroup_perMainExample_perSubExample) 。 但是,实际上数组或列表中的项目分别是OxFordDefinition_perGroup_perMainExample_perSubExample[]List类型,当然不能将其分配给此类型。 此XmlSerializer代码生成失败。

如果完全从[XmlArrayItem]属性中删除类型设置,那么您的类型的两个版本都可以序列化为XML:

 [System.Xml.Serialization.XmlArrayItemAttribute("_perSubExample", IsNullable = false)] public List> _perMainExample { get { return this._perMainExampleField; } set { this._perMainExampleField = value; } } 

样品小提琴 。

更新

你问, 它增加了不应该存在的额外层。 任何的想法?

这是因为您使用的是嵌套列表或锯齿状数组。 将其更改为简单列表或一维数组:

 private List _perMainExampleField; ///  [System.Xml.Serialization.XmlArrayItemAttribute("_perSubExample", IsNullable = false)] public List _perMainExample { get { return this._perMainExampleField; } set { this._perMainExampleField = value; } } 

样品小提琴#2 。

然后我从http://pastebin.com/raw/BJhRfFNf下载了整个XML并运行xsd.exe以生成模式,然后从XML中生成类,我能够重现您的问题 – 生成了错误的类。 然后我手动将锯齿状数组更改为平面数组( List也能正常工作)并能够序列化和反序列化XML,而不会抛出exception:

样品小提琴#3 。

不幸的是,似乎只有第一个 节点使用这些调整的类成功反序列化,所以此时这个自动生成的代码似乎不可行。

我不确定为什么xsd.exe在这里生成了错误的代码,你可能想问另一个问题或者打开微软的问题。

最后更新

看起来xsd.exe (以及粘贴XML作为类 )在包含嵌套重复元素的重复元素时遇到问题:

 <_permainexample> <_persubexample>  <_persubexample>   <_permainexample> <_persubexample>  <_persubexample>   

我不确定问题是什么,但此时我建议切换到不同的代码生成工具,例如https://xmltocsharp.azurewebsites.net/ ,它会生成以下类:

 [XmlRoot(ElementName="_Example")] public class _Example { [XmlElement(ElementName="_SenseNot")] public string _SenseNot { get; set; } [XmlElement(ElementName="_GrammaticNot")] public string _GrammaticNot { get; set; } [XmlElement(ElementName="_Desc")] public string _Desc { get; set; } } [XmlRoot(ElementName="_perSubExample")] public class _perSubExample { [XmlElement(ElementName="_UpperTitle")] public string _UpperTitle { get; set; } [XmlElement(ElementName="_FormGroup")] public string _FormGroup { get; set; } [XmlElement(ElementName="_SenseNot")] public string _SenseNot { get; set; } [XmlElement(ElementName="_GrammaticNot")] public string _GrammaticNot { get; set; } [XmlElement(ElementName="_Desc")] public string _Desc { get; set; } [XmlElement(ElementName="_Example")] public List<_example> _Example { get; set; } [XmlElement(ElementName="_Synonyms")] public string _Synonyms { get; set; } } [XmlRoot(ElementName="_perMainExample")] public class _perMainExample { [XmlElement(ElementName="_perSubExample")] public List<_persubexample> _perSubExample { get; set; } } [XmlRoot(ElementName="_perGroup")] public class _perGroup { [XmlElement(ElementName="_GroupDesc")] public string _GroupDesc { get; set; } [XmlElement(ElementName="_GroupSense")] public string _GroupSense { get; set; } [XmlElement(ElementName="_GroupGrammer")] public string _GroupGrammer { get; set; } [XmlElement(ElementName="_perMainExample")] public List<_permainexample> _perMainExample { get; set; } } [XmlRoot(ElementName="OxFordDefinition")] public class OxFordDefinition { [XmlElement(ElementName="sourceURL")] public string SourceURL { get; set; } [XmlElement(ElementName="originDesc")] public string OriginDesc { get; set; } [XmlElement(ElementName="_perGroup")] public List<_pergroup> _perGroup { get; set; } } 

请注意:

  1. 生成的代码更清晰。

  2. 添加了一个额外级别的类_perMainExample来封装内部_perSubExample列表。

示例小提琴#4通过调用XNode.DeepEquals()显示原始和重新序列化的XML是相同的。