如何序列化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; } }
请注意:
-
生成的代码更清晰。
-
添加了一个额外级别的类
_perMainExample
来封装内部_perSubExample
列表。
示例小提琴#4通过调用XNode.DeepEquals()
显示原始和重新序列化的XML是相同的。