it's me again.
I'm currently stuck at deserializing a specific XML file, which gives me headaches.
The XML that needs to be deserialized:
<AuditEntryData>
<AuditEntryValue name="Supplier name" newValue="Assagne Corp." type="Text" />
<AuditEntryValue name="MODDATETIME" oldValue="2021-09-15T17:07:37.0000000Z" newValue="2021-09-15T17:29:27.0000000Z" type="DateTime" />
<AuditEntryTableValues>
<T name="InvoiceItems">
<Columns>
<C name="Name" type="Text" />
<C name="Accounting-Key" type="Text" />
<C name="AdditionalColumn" type="Text" />
<C name="Date" type="Date" />
<C name="Value" type="Number" />
</Columns>
<OldValues>
<R>
<C>Oh Long Johnson</C>
<C>23ufztg3u4ghf</C>
<C>Test33</C>
<C>2021-02-10T00:00:00.0000000Z</C>
<C>18.73</C>
</R>
</OldValues>
<NewValues>
<R>
<C>John Smith</C>
<C>23ufztg3u4ghf</C>
<C>Test33</C>
<C>2021-02-10T00:00:00.0000000Z</C>
<C>18.73</C>
</R>
<R>
<C>Johnathan Smith</C>
<C>eui5dctmcotgu</C>
<C>Test22</C>
<C>2021-09-15T00:00:00.0000000Z</C>
<C>13.12</C>
</R>
</NewValues>
</T>
</AuditEntryTableValues>
</AuditEntryData>
The class file generated with xsd:
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3928.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class C {
private string nameField;
private string typeField;
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string name {
get {
return this.nameField;
}
set {
this.nameField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string type {
get {
return this.typeField;
}
set {
this.typeField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3928.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class R {
private C[] cField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("C")]
public C[] C {
get {
return this.cField;
}
set {
this.cField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3928.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class AuditEntryData {
private object[] itemsField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("AuditEntryTableValues", typeof(AuditEntryDataAuditEntryTableValues), Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
[System.Xml.Serialization.XmlElementAttribute("AuditEntryValue", typeof(AuditEntryDataAuditEntryValue), Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
[System.Xml.Serialization.XmlElementAttribute("C", typeof(C))]
[System.Xml.Serialization.XmlElementAttribute("R", typeof(R))]
public object[] Items {
get {
return this.itemsField;
}
set {
this.itemsField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3928.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class AuditEntryDataAuditEntryTableValues {
private AuditEntryDataAuditEntryTableValuesT[] tField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("T", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public AuditEntryDataAuditEntryTableValuesT[] T {
get {
return this.tField;
}
set {
this.tField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3928.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class AuditEntryDataAuditEntryTableValuesT {
private C[][] columnsField;
private C[][][] oldValuesField;
private C[][][] newValuesField;
private string nameField;
/// <remarks/>
[System.Xml.Serialization.XmlArrayAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
[System.Xml.Serialization.XmlArrayItemAttribute("C", typeof(C), IsNullable=false)]
public C[][] Columns {
get {
return this.columnsField;
}
set {
this.columnsField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlArrayAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
[System.Xml.Serialization.XmlArrayItemAttribute("R", typeof(C[]), IsNullable=false)]
[System.Xml.Serialization.XmlArrayItemAttribute("C", typeof(C), IsNullable=false, NestingLevel=1)]
public C[][][] OldValues {
get {
return this.oldValuesField;
}
set {
this.oldValuesField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlArrayAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
[System.Xml.Serialization.XmlArrayItemAttribute("R", typeof(C[]), IsNullable=false)]
[System.Xml.Serialization.XmlArrayItemAttribute("C", typeof(C), IsNullable=false, NestingLevel=1)]
public C[][][] NewValues {
get {
return this.newValuesField;
}
set {
this.newValuesField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string name {
get {
return this.nameField;
}
set {
this.nameField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3928.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class AuditEntryDataAuditEntryValue {
private string nameField;
private string newValueField;
private string typeField;
private string oldValueField;
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string name {
get {
return this.nameField;
}
set {
this.nameField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string newValue {
get {
return this.newValueField;
}
set {
this.newValueField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string type {
get {
return this.typeField;
}
set {
this.typeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string oldValue {
get {
return this.oldValueField;
}
set {
this.oldValueField = value;
}
}
}
Deserializing the xml gives me the following error:
Multi dimensional arrays:
Unable to generate a temporary class (result=1).
error CS0030: Cannot convert type 'C[]' to 'C'
error CS0030: Cannot convert type 'C[][]' to 'C[]'
error CS0029: Cannot implicitly convert type 'C' to 'C[]'
error CS0029: Cannot implicitly convert type 'C[]' to 'C[][]
Single dimensional arrays (after modifying the class file):
Unable to generate a temporary class (result=1).
error CS0030: Cannot convert type 'C' to 'C[]'
error CS0029: Cannot implicitly convert type 'C[]' to 'C'
The xml is produced by an external program, so I have no control over it. Changing the format therefore is not possible. If I remove/comment out the type attribute declarations, I am able to load the XML, but it won't load the OldValues and NewValues.
Could someone point me to the right direction?
CodePudding user response:
Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication2
{
class Program
{
const string FILE = @"c:\TEMP\TEST.XML";
static void Main(string[] args)
{
XmlReader reader = XmlReader.Create(FILE);
XmlSerializer serializer = new XmlSerializer(typeof(AuditEntryData));
AuditEntryData auditEntryData = (AuditEntryData)serializer.Deserialize(reader);
}
}
public class AuditEntryData
{
[XmlElement()]
public AuditEntryValue[] AuditEntryValue { get; set; }
[XmlArray("AuditEntryTableValues")]
[XmlArrayItem("T")]
public AuditEntryTableValue[] AuditEntryTableValue { get; set; }
}
public class AuditEntryValue
{
[XmlAttribute]
public string name { get; set; }
[XmlAttribute]
public string newValue { get; set; }
[XmlAttribute]
public string oldValue { get; set; }
[XmlAttribute]
public string type { get; set; }
}
public class AuditEntryTableValue
{
[XmlAttribute]
public string name { get; set; }
[XmlArray("Columns")]
[XmlArrayItem("C")]
public Column[] Columns { get; set; }
[XmlArray("OldValues")]
[XmlArrayItem("R")]
public OldValue[] OldValues { get; set; }
[XmlArray("NewValues")]
[XmlArrayItem("R")]
public NewValue[] NewValues { get; set; }
}
public class Column
{
[XmlAttribute]
public string name { get; set; }
[XmlAttribute]
public string type { get; set; }
}
public class OldValue
{
[XmlElement]
public string[] C{ get; set; }
}
public class NewValue
{
[XmlElement]
public string[] C { get; set; }
}
}
CodePudding user response:
Here is a working simplified example.
Just use XML.Run()
.
Probably OldValues and NewValues class may be merged into one class only, by specifying the ElementName
.
public class XML
{
private readonly string xml = @"
<AuditEntryData>
<AuditEntryValue name=""Supplier name"" newValue=""Assagne Corp."" type=""Text"" />
<AuditEntryValue name=""MODDATETIME"" oldValue=""2021-09-15T17:07:37.0000000Z"" newValue=""2021-09-15T17:29:27.0000000Z"" type=""DateTime"" />
<AuditEntryTableValues>
<T name=""InvoiceItems"">
<Columns>
<C name=""Name"" type=""Text"" />
<C name=""Accounting-Key"" type=""Text"" />
<C name=""AdditionalColumn"" type=""Text"" />
<C name=""Date"" type=""Date"" />
<C name=""Value"" type=""Number"" />
</Columns>
<OldValues>
<R>
<C>Oh Long Johnson</C>
<C>23ufztg3u4ghf</C>
<C>Test33</C>
<C>2021-02-10T00:00:00.0000000Z</C>
<C>18.73</C>
</R>
</OldValues>
<NewValues>
<R>
<C>John Smith</C>
<C>23ufztg3u4ghf</C>
<C>Test33</C>
<C>2021-02-10T00:00:00.0000000Z</C>
<C>18.73</C>
</R>
<R>
<C>Johnathan Smith</C>
<C>eui5dctmcotgu</C>
<C>Test22</C>
<C>2021-09-15T00:00:00.0000000Z</C>
<C>13.12</C>
</R>
</NewValues>
</T>
</AuditEntryTableValues>
</AuditEntryData>
";
public void Run()
{
var stream = new MemoryStream();
var writer = new StreamWriter(stream);
writer.Write(xml);
writer.Flush();
stream.Position = 0;
var ser = new XmlSerializer(typeof(AuditEntryData));
var o = (AuditEntryData)ser.Deserialize(stream);
}
[XmlRoot]
public class AuditEntryData
{
[XmlElement("AuditEntryValue")]
public List<AuditEntryValue> AuditEntryValues { get; set; }
[XmlElement]
public AuditEntryTableValues AuditEntryTableValues { get; set; }
}
public class AuditEntryValue
{
[XmlAttribute]
public string name { get; set; }
[XmlAttribute]
public string oldValue { get; set; }
[XmlAttribute]
public string newValue { get; set; }
[XmlAttribute]
public string type { get; set; }
}
public class AuditEntryTableValues
{
[XmlElement]
public T T { get; set; }
}
public class T
{
[XmlAttribute]
public string name { get; set; }
[XmlElement]
public Columns Columns { get; set; }
[XmlElement]
public OldValues OldValues { get; set; }
[XmlElement]
public NewValues NewValues { get; set; }
}
public class Columns
{
[XmlElement(ElementName = "C", Type = typeof(C))]
public List<C> Cs { get; set; }
}
public class C
{
[XmlAttribute]
public string name { get; set; }
[XmlAttribute]
public string type { get; set; }
}
public class OldValues
{
[XmlElement]
public R R { get; set; }
}
public class NewValues
{
[XmlElement]
public R R { get; set; }
}
public class R
{
[XmlElement(ElementName = "C")]
public List<string> Cs { get; set; }
}
}