如何序列化List<List<object>>?
How to serialize List<List<object>>?
框架是 c# .net 4.6.2
我正在从 XML 代码
生成自动 XML classes
当我自动生成时,它会自动转换为Array[][]
但我想将其用作 List<List<>>
而且我确信我从 Array 到 List 的对话会导致一些序列化错误。我认为这是关于获取和设置功能。所以我需要你的帮助来解决这个问题
这里是当我 编辑 > 选择性粘贴 > 粘贴 XML 为 classes
时自动生成的代码片段
/// <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 class
的完整代码
这是它给出的错误
其实你的原版和修改后的OxFordDefinition_perGroup
都无法序列化成功。问题是 XmlArrayItem.Type
, which is the second argument to the constructor:
的值
[System.Xml.Serialization.XmlArrayItemAttribute("_perSubExample", typeof(OxFordDefinition_perGroup_perMainExample_perSubExample), IsNullable = false)]
public OxFordDefinition_perGroup_perMainExample_perSubExample[][] { get; set; }
根据 docs
Use the Type property to specify an overridden type for a public field or public read/write property value.
If a field or property returns an array of type Object, apply multiple instances of the XmlArrayItemAttribute
to the field or property. For each instance, set the Type property to a type of object that can be inserted into the array.
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;
}
}
示例 fiddle.
更新
你问,它添加了不应该存在的额外层。有什么想法吗?
这是因为您正在使用嵌套列表或交错数组。将其更改为简单列表或一维数组:
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;
}
}
样本fiddle #2.
然后我从 http://pastebin.com/raw/BJhRfFNf 和 运行 xsd.exe
下载了整个 XML 来生成一个模式,然后 classes,从 XML,并且我能够重现您的问题 - 生成了不正确的 classes。然后我手动将锯齿状数组更改为平面数组(List<T>
也可以正常工作)并且能够序列化和反序列化 XML 而不会抛出异常:
样本fiddle #3.
不幸的是,似乎只有 first </_perMainExample>
节点使用这些调整后的 classes 成功反序列化,所以此时这个自动生成的代码似乎不可行。
我不确定为什么 xsd.exe
会在此处生成错误代码,您可能想问另一个问题或向 Microsoft 提出问题。
最终更新
看起来 xsd.exe
(因此 将 XML 粘贴为 类)在处理包含嵌套的重复元素时遇到了问题重复元素:
<_perMainExample>
<_perSubExample>
</_perSubExample>
<_perSubExample>
</_perSubExample>
</_perMainExample>
<_perMainExample>
<_perSubExample>
</_perSubExample>
<_perSubExample>
</_perSubExample>
</_perMainExample>
我不确定问题出在哪里,但此时我建议切换到其他代码生成工具,例如 https://xmltocsharp.azurewebsites.net/,它会生成以下 classes:
[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; }
}
注意:
生成的代码非常干净。
增加了一层class_perMainExample
来封装内部_perSubExample
列表。
示例 fiddle #4 显示原始和重新序列化的 XML 通过调用 XNode.DeepEquals()
.
相同
框架是 c# .net 4.6.2
我正在从 XML 代码
生成自动 XML classes当我自动生成时,它会自动转换为Array[][]
但我想将其用作 List<List<>>
而且我确信我从 Array 到 List 的对话会导致一些序列化错误。我认为这是关于获取和设置功能。所以我需要你的帮助来解决这个问题
这里是当我 编辑 > 选择性粘贴 > 粘贴 XML 为 classes
时自动生成的代码片段 /// <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 class
的完整代码这是它给出的错误
其实你的原版和修改后的OxFordDefinition_perGroup
都无法序列化成功。问题是 XmlArrayItem.Type
, which is the second argument to the constructor:
[System.Xml.Serialization.XmlArrayItemAttribute("_perSubExample", typeof(OxFordDefinition_perGroup_perMainExample_perSubExample), IsNullable = false)]
public OxFordDefinition_perGroup_perMainExample_perSubExample[][] { get; set; }
根据 docs
Use the Type property to specify an overridden type for a public field or public read/write property value.
If a field or property returns an array of type Object, apply multiple instances of the
XmlArrayItemAttribute
to the field or property. For each instance, set the Type property to a type of object that can be inserted into the array.
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;
}
}
示例 fiddle.
更新
你问,它添加了不应该存在的额外层。有什么想法吗?
这是因为您正在使用嵌套列表或交错数组。将其更改为简单列表或一维数组:
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;
}
}
样本fiddle #2.
然后我从 http://pastebin.com/raw/BJhRfFNf 和 运行 xsd.exe
下载了整个 XML 来生成一个模式,然后 classes,从 XML,并且我能够重现您的问题 - 生成了不正确的 classes。然后我手动将锯齿状数组更改为平面数组(List<T>
也可以正常工作)并且能够序列化和反序列化 XML 而不会抛出异常:
样本fiddle #3.
不幸的是,似乎只有 first </_perMainExample>
节点使用这些调整后的 classes 成功反序列化,所以此时这个自动生成的代码似乎不可行。
我不确定为什么 xsd.exe
会在此处生成错误代码,您可能想问另一个问题或向 Microsoft 提出问题。
最终更新
看起来 xsd.exe
(因此 将 XML 粘贴为 类)在处理包含嵌套的重复元素时遇到了问题重复元素:
<_perMainExample>
<_perSubExample>
</_perSubExample>
<_perSubExample>
</_perSubExample>
</_perMainExample>
<_perMainExample>
<_perSubExample>
</_perSubExample>
<_perSubExample>
</_perSubExample>
</_perMainExample>
我不确定问题出在哪里,但此时我建议切换到其他代码生成工具,例如 https://xmltocsharp.azurewebsites.net/,它会生成以下 classes:
[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; }
}
注意:
生成的代码非常干净。
增加了一层class
_perMainExample
来封装内部_perSubExample
列表。
示例 fiddle #4 显示原始和重新序列化的 XML 通过调用 XNode.DeepEquals()
.