Actually neither your original nor your modified OxFordDefinition_perGroup
can be serialized successfully. The problem is your value for 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; }
According to the 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.
The typeof(OxFordDefinition_perGroup_perMainExample_perSubExample)
indicates that items in the outermost collection will be of type typeof(OxFordDefinition_perGroup_perMainExample_perSubExample)
. However, in fact the items in the array or list are of type OxFordDefinition_perGroup_perMainExample_perSubExample[]
or List<OxFordDefinition_perGroup_perMainExample_perSubExample>
respectively, which cannot, of course, be assigned to this type. This XmlSerializer
code generation fails.
If you remove the type setting entirely from your [XmlArrayItem]
attribute then both versions of your type will be serializable to XML:
[System.Xml.Serialization.XmlArrayItemAttribute("_perSubExample", IsNullable = false)]
public List<List<OxFordDefinition_perGroup_perMainExample_perSubExample>> _perMainExample
{
get
{
return this._perMainExampleField;
}
set
{
this._perMainExampleField = value;
}
}
Sample fiddle.
Update
You asked, it adds extra layer which should not exists. any idea?
This is because you are using nested lists or jagged arrays. Change it to be a simple list or 1-d array:
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;
}
}
Sample fiddle #2.
I then downloaded the entire XML from http://pastebin.com/raw/BJhRfFNf and ran xsd.exe
to generate a schema, and then classes, from the XML, and I was able to reproduce your problem - incorrect classes were generated. I then manually changed the jagged array to a flat array (a List<T>
would work fine also) and was able to serialize and deserialize the XML without an exception getting thrown:
Sample fiddle #3.
Unfortunately, it appears that only the first </_perMainExample>
node is successfully deserialized using these tweaked classes, so at this point this auto-generated code just doesn't seem viable.
I'm not sure why xsd.exe
generated bad code here, you might want to ask another question or open an issue with Microsoft.
Final Update
It looks as though xsd.exe
(and thus Paste XML as Classes) is having trouble with a repeating element that contains nested repeating elements:
<_perMainExample>
<_perSubExample>
</_perSubExample>
<_perSubExample>
</_perSubExample>
</_perMainExample>
<_perMainExample>
<_perSubExample>
</_perSubExample>
<_perSubExample>
</_perSubExample>
</_perMainExample>
I'm not sure what the problem is, but at this point I recommend switching to a different code-generation tool such as https://xmltocsharp.azurewebsites.net/, which generates the following 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; }
}
Notice that:
The code generated is much, much cleaner.
An extra level of class _perMainExample
is added to encapsulate the inner _perSubExample
list.
Sample fiddle #4 which shows that the original and re-serialized XML are identical by calling XNode.DeepEquals()
.