[英]How to serialize List<List<object>>?
框架是c#.net 4.6.2
我正在从XML代码生成自动XML类
当我自动生成时,它会自动转换为Array[][]
但我想将其用作List<List<>>
而且我确信从Array到List的对话会导致一些序列化错误。 我认为这与获取和设置功能有关。 因此,我需要您的帮助来解决此问题
这是我编辑>粘贴特殊>将XML粘贴为类时自动生成的代码段
/// <remarks/>
[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;
/// <remarks/>
public string _GroupDesc
{
get
{
return this._GroupDescField;
}
set
{
this._GroupDescField = value;
}
}
/// <remarks/>
public string _GroupSense
{
get
{
return this._GroupSenseField;
}
set
{
this._GroupSenseField = value;
}
}
/// <remarks/>
public string _GroupGrammer
{
get
{
return this._GroupGrammerField;
}
set
{
this._GroupGrammerField = value;
}
}
/// <remarks/>
[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<>>
而不是数组
所以我像下面这样
/// <remarks/>
[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<OxFordDefinition_perGroup_perMainExample_perSubExample>> _perMainExampleField;
/// <remarks/>
public string _GroupDesc
{
get
{
return this._GroupDescField;
}
set
{
this._GroupDescField = value;
}
}
/// <remarks/>
public string _GroupSense
{
get
{
return this._GroupSenseField;
}
set
{
this._GroupSenseField = value;
}
}
/// <remarks/>
public string _GroupGrammer
{
get
{
return this._GroupGrammerField;
}
set
{
this._GroupGrammerField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlArrayItemAttribute("_perSubExample", typeof(OxFordDefinition_perGroup_perMainExample_perSubExample), IsNullable = false)]
public List<List<OxFordDefinition_perGroup_perMainExample_perSubExample>> _perMainExample
{
get
{
return this._perMainExampleField;
}
set
{
this._perMainExampleField = value;
}
}
}
但是这一次当我尝试如下序列化时,它给出了序列化错误
public static string SerializeXML<T>(this T toSerialize)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
StringWriter textWriter = new StringWriter();
xmlSerializer.Serialize(textWriter, toSerialize);
return textWriter.ToString();
}
这里是XML类的完整代码
这里给出的错误
实际上,原始的或修改的OxFordDefinition_perGroup
都无法成功序列化。 问题是您的XmlArrayItem.Type
值是构造函数的第二个参数:
[System.Xml.Serialization.XmlArrayItemAttribute("_perSubExample", typeof(OxFordDefinition_perGroup_perMainExample_perSubExample), IsNullable = false)]
public OxFordDefinition_perGroup_perMainExample_perSubExample[][] { get; set; }
根据文档
使用Type属性为公共字段或公共读/写属性值指定重写的类型。
如果字段或属性返回对象类型的数组,则将
XmlArrayItemAttribute
多个实例应用于该字段或属性。 对于每个实例,将Type属性设置为可以插入数组的对象的类型。
typeof(OxFordDefinition_perGroup_perMainExample_perSubExample)
指示最外面的集合中的项目类型为typeof(OxFordDefinition_perGroup_perMainExample_perSubExample)
。 但是,实际上,数组或列表中的项目分别是OxFordDefinition_perGroup_perMainExample_perSubExample[]
或List<OxFordDefinition_perGroup_perMainExample_perSubExample>
类型,它们当然不能分配给该类型。 XmlSerializer
代码生成失败。
如果您从[XmlArrayItem]
属性中完全删除类型设置,则该类型的两个版本都可以序列化为XML:
[System.Xml.Serialization.XmlArrayItemAttribute("_perSubExample", IsNullable = false)]
public List<List<OxFordDefinition_perGroup_perMainExample_perSubExample>> _perMainExample
{
get
{
return this._perMainExampleField;
}
set
{
this._perMainExampleField = value;
}
}
样品提琴 。
更新资料
您询问, 它添加了不应该存在的额外层。 任何想法?
这是因为您使用的是嵌套列表或锯齿状数组。 将其更改为简单列表或一维数组:
private List<OxFordDefinition_perGroup_perMainExample_perSubExample> _perMainExampleField;
/// <remarks/>
[System.Xml.Serialization.XmlArrayItemAttribute("_perSubExample", IsNullable = false)]
public List<OxFordDefinition_perGroup_perMainExample_perSubExample> _perMainExample
{
get
{
return this._perMainExampleField;
}
set
{
this._perMainExampleField = value;
}
}
样本小提琴2 。
然后,我从http://pastebin.com/raw/BJhRfFNf下载了整个XML,并运行xsd.exe
生成了一个架构,然后从该XML中生成了类,并且我能够重现您的问题-生成了错误的类。 然后,我手动将锯齿状的数组更改为平面数组( List<T>
也可以正常工作),并且能够对XML进行序列化和反序列化,而不会引发异常:
样本小提琴#3 。
不幸的是,使用这些经过调整的类,似乎只有第一个 </_perMainExample>
节点已成功反序列化,因此,此时此自动生成的代码似乎并不可行。
我不确定为什么xsd.exe
在这里生成了错误的代码,您可能想问另一个问题或与Microsoft打开问题。
最终更新
看起来xsd.exe
(因此将XML粘贴为xsd.exe
)在包含嵌套的重复元素的重复元素方面遇到了麻烦:
<_perMainExample>
<_perSubExample>
</_perSubExample>
<_perSubExample>
</_perSubExample>
</_perMainExample>
<_perMainExample>
<_perSubExample>
</_perSubExample>
<_perSubExample>
</_perSubExample>
</_perMainExample>
我不确定是什么问题,但是在这一点上,我建议切换到其他代码生成工具,例如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和重新序列化的XML是相同的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.