Home > Software design >  C# XML deserialization issues / Unable to generate a temporary class (result=1)
C# XML deserialization issues / Unable to generate a temporary class (result=1)

Time:10-19

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; }
        }
    }
  • Related