Search code examples
c#xmlerror-handlingxsdxmlserializer

Error deserializing XML in C#


Here is my code for deserialization in C#:

private void button1_Click(object sender, EventArgs e)
    {
        LandXML myObject;
        XmlSerializer mySerializer =
        new XmlSerializer(typeof(LandXML));
        FileStream myFileStream =
        new FileStream("Nova 6.xml", FileMode.Open);
        myObject = (LandXML)
        mySerializer.Deserialize(myFileStream);
    }

I've generated classes from link http://www.landxml.org/schema/LandXML-1.2/LandXML-1.2.xsd using Visual Studio's tool xsd.exe. I have some generic file based on LandXML Schema (XSD and that XML file are checked for compatibility at http://www.utilities-online.info/xsdvalidation/#.VtBcNeaT6YA, and they are compatible). The thing is that my code never get further than:

XmlSerializer mySerializer =
    new XmlSerializer(typeof(LandXML));

and I get an error (this is only a part of error trace)

'TunnelCore.Utilities.LandXML12.LandXML'. System.InvalidOperationException: There was an error reflecting type 'TunnelCore.Utilities.LandXML12.LandXML'. ---> System.InvalidOperationException: There was an error reflecting property 'Items'. ---> System.InvalidOperationException: There was an error reflecting type 'TunnelCore.Utilities.LandXML12.PlanFeatures'. ---> System.InvalidOperationException: There was an error reflecting property 'PlanFeature'. ---> System.InvalidOperationException: There was an error reflecting type 'TunnelCore.Utilities.LandXML12.PlanFeature'. ---> System.InvalidOperationException: There was an error reflecting property 'Items'. ---> System.InvalidOperationException: There was an error reflecting type 'TunnelCore.Utilities.LandXML12.CoordGeom'. ---> System.InvalidOperationException: There was an error reflecting property 'Items'. ---> System.InvalidOperationException: There was an error reflecting type 'TunnelCore.Utilities.LandXML12.IrregularLine'. ---> System.InvalidOperationException: There was an error reflecting property 'Item'. ---> System.InvalidOperationException: The type for XmlElement may not be specified for primitive types. at System.Xml.Serialization.XmlReflectionImporter.ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, String ns, Type choiceIdentifierType, Boolean rpc, Boolean openModel, RecursionLimiter limiter) at System.Xml.Serialization.XmlReflectionImporter.ImportFieldMapping(StructModel parent, FieldModel model, XmlAttributes a, String ns, RecursionLimiter limiter) at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter) --- End of inner exception stack trace --- at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter) at System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter) at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)

I'm new at programming, but I think that this part is maybe crucial:

...System.InvalidOperationException: The type for XmlElement may not be specified for primitive types.

Can someone, please, help to parse and create this classes correctly. Sample XML files for testing can be found at:

http://landxml.org/schema/LandXML-1.1/samples/TopoCAD/Alignments%20and%20length%20table.xml


Solution

  • Following your steps I created the classes and compared the irregular line class to the Boundary class since both have a choice that has only 2 items PntList2d/3d.

    For Irregular Line

        [System.Xml.Serialization.XmlElementAttribute("PntList2D", typeof(string))]
        [System.Xml.Serialization.XmlElementAttribute("PntList3D", typeof(string))]
        [System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemElementName")]
        public double Item {
            get {
                return this.itemField;
            }
            set {
                this.itemField = value;
            }
        }
    
        /// <remarks/>
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public ItemChoiceType ItemElementName {
            get {
                return this.itemElementNameField;
            }
            set {
                this.itemElementNameField = value;
            }
        }
    

    And For Boundary

        [System.Xml.Serialization.XmlElementAttribute("PntList2D", typeof(string))]
        [System.Xml.Serialization.XmlElementAttribute("PntList3D", typeof(string))]
        public object Item {
            get {
                return this.itemField;
            }
            set {
                this.itemField = value;
            }
        }
    

    I believe your issue is Irregular lines Item field is a double and The return type for Item is also a double.

    Changing both to object will get rid of the error

    BUT you have more errors...

    Notice that boundary doesn't have

    [System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemElementName")]
    

    It also doesnt have

    private ItemChoiceType itemElementNameField;
    
    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public ItemChoiceType ItemElementName {
        get {
            return this.itemElementNameField;
        }
        set {
            this.itemElementNameField = value;
        }
    }
    

    You will need to add these as well in a few different areas (it will tell you where). You were correct about the error being crucial. Each place you need to make changes will be at the bottom of those nested inner exceptions. Keep working at it, there are probably several errors that will only appear once you get rid of the error before it. Apparently xsd.exe makes a few mistakes with choices