框架是c#.net 4.6.2
我正在从XML代码生成自动XML类
当我自动生成时,它会自动转换为Array[][]
但我想将其用作List<List<>>
我确信从Array到List的对话会导致一些序列化错误。我认为这是关于获取和设置功能。所以我需要你的帮助来解决这个问题
这是我编辑&gt;时自动生成的代码段粘贴特殊&gt;将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类的完整代码
这里给出的错误
答案 0 :(得分:2)
实际上,您的原始版本和修改后的OxFordDefinition_perGroup
都无法成功序列化。问题是XmlArrayItem.Type
的值,这是constructor的第二个参数:
[System.Xml.Serialization.XmlArrayItemAttribute("_perSubExample", typeof(OxFordDefinition_perGroup_perMainExample_perSubExample), IsNullable = false)]
public OxFordDefinition_perGroup_perMainExample_perSubExample[][] { get; set; }
根据docs
使用Type属性为公共字段或公共读/写属性值指定重写类型。
如果字段或属性返回Object类型的数组,则将
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;
}
}
示例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下载了整个XML并运行xsd.exe
以生成模式,然后从XML中生成类,并且我能够重现您的问题 - 生成了错误的类。然后我手动将锯齿状数组更改为平面数组(List<T>
也能正常工作)并能够序列化和反序列化XML,而不会抛出异常:
示例fiddle #3。
不幸的是,似乎只有第一个 </_perMainExample>
节点使用这些调整的类成功反序列化,所以此时这个自动生成的代码似乎不可行。
我不确定为什么xsd.exe
会在此处生成错误的代码,您可能想要提出另一个问题或者向Microsoft提出问题。
最终更新
看起来好像xsd.exe
(因此将XML粘贴为类)在包含嵌套重复元素的重复元素时出现问题:
<_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
列表。
示例fiddle #4,通过调用XNode.DeepEquals()
来显示原始和重新序列化的XML是相同的。