none
Deserialize XML File RRS feed

  • Question

  • I have spent a few hours trying to deserialize and XML file but still fail. I boiled it down to the following which WORKS:

    XML File:
    <Entities xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
      <Entity>
        <Name>a</Name>
      </Entity>
      <Entity>
        <Name>b</Name>
      </Entity>
    </Entities>

    On this I run xsd.exe which generates a class. That class is kind of long so I won't list it here but I list the one that doesn't work at the bottom. Anyways, here is how I deserialize the XML file:
    XmlSerializer ser = new XmlSerializer(typeof(Entities));
    FileStream fs = new FileStream("Input.xml", FileMode.Open);
    Entities ents = (Entities)ser.Deserialize(fs);

    This works fine. However, my XML file has some extension like this:
    <Entities xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
      <Entity>
        <Name>a</Name>
        <Properties>
          <Property>
            <Name>aa1Name</Name>
          </Property>
          <Property>
            <Name>aa2Name</Name>
          </Property>
        </Properties>
      </Entity>
      <Entity>
        <Name>b</Name>
      </Entity>
    </Entities>

    Now if I run the same code as above I get the error:
    Unable to generate a temporary class (result=1).
    error CS0030: Cannot convert type '[Namespace].EntitiesEntityPropertiesProperty[]' to '[Namespace].EntitiesEntityPropertiesProperty'
    error CS0029: Cannot implicitly convert type '[Namespace].EntitiesEntityPropertiesProperty' to '[Namespace].EntitiesEntityPropertiesProperty[]'

    Why does this not work? I am just adding another level to the XML file and regenerate the class with xsd.exe

    Here is the class that xsd.exe generated for the xml file that has the Properties section:
    namespace [Namespace] {
        using System.Xml.Serialization;
        /// <remarks/>
        [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
        [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 Entities {
           
            private EntitiesEntity[] itemsField;
           
            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute("Entity", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
            public EntitiesEntity[] Items {
                get {
                    return this.itemsField;
                }
                set {
                    this.itemsField = value;
                }
            }
        }
       
        /// <remarks/>
        [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
        [System.SerializableAttribute()]
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.ComponentModel.DesignerCategoryAttribute("code")]
        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
        public partial class EntitiesEntity {
           
            private string nameField;
           
            private EntitiesEntityPropertiesProperty[][] propertiesField;
           
            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
            public string Name {
                get {
                    return this.nameField;
                }
                set {
                    this.nameField = value;
                }
            }
           
            /// <remarks/>
            [System.Xml.Serialization.XmlArrayAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
            [System.Xml.Serialization.XmlArrayItemAttribute("Property", typeof(EntitiesEntityPropertiesProperty), Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=false)]
            public EntitiesEntityPropertiesProperty[][] Properties {
                get {
                    return this.propertiesField;
                }
                set {
                    this.propertiesField = value;
                }
            }
        }
       
        /// <remarks/>
        [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
        [System.SerializableAttribute()]
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.ComponentModel.DesignerCategoryAttribute("code")]
        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
        public partial class EntitiesEntityPropertiesProperty {
           
            private string nameField;
           
            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
            public string Name {
                get {
                    return this.nameField;
                }
                set {
                    this.nameField = value;
                }
            }
        }
    }


    • Edited by hfaun Saturday, December 16, 2017 7:55 AM Spelling
    Saturday, December 16, 2017 7:51 AM

All replies

  • Try a different method: copy the XML text to Clipboard, then go to Visual Studio, to some code file, and execute from menu: Edit, Paste Special, Paste XML as Classes.

    Seems that you should replace ‘[][]’ with ‘[]’.

    Saturday, December 16, 2017 8:25 AM
  • Try a different method: copy the XML text to Clipboard, then go to Visual Studio, to some code file, and execute from menu: Edit, Paste Special, Paste XML as Classes.

    Seems that you should replace ‘[][]’ with ‘[]’.

    I think this is correct. I'm not sure why the xsd.exe generates the Properties-Array as an 2-dimension array. Using the method recommended by Viorel the array is generated correctly. Simplified your class structure should look smething like this:

    [XmlRoot("Entities", IsNullable = false)]
        public class xmlEntities
        {
            private xmlEntitiesEntity[] MyEntities;
    
            [XmlElement("Entity")]
            public xmlEntitiesEntity[] EntityItems
            {
                get { return MyEntities; }
                set { MyEntities = value; }
            }
        }
    
        public class xmlEntitiesEntity
        {
            private string MyName;
            private xmlEntitiesEntityProperties MyProperties;
    
            public string Name
            {
                get { return MyName; }
                set { MyName = value; }
            }
    
            public xmlEntitiesEntityProperties Properties
            {
                get { return MyProperties; }
                set { MyProperties = value; }
            }
    
        }
    
        public class xmlEntitiesEntityProperties
        {
            private xmlEntitiesEntityPropertiesProperty[] MyProperty;
    
            [XmlElement("Property")]
            public xmlEntitiesEntityPropertiesProperty[] Property
            {
                get { return MyProperty; }
                set { MyProperty = value; }
            }
        }
    
        public class xmlEntitiesEntityPropertiesProperty
        {
            private string MyName;
    
            public string Name
            {
                get { return MyName; }
                set { MyName = Name; }
            }
        }

    Saturday, December 16, 2017 11:24 AM
  • Quote: "Try a different method: copy the XML text to Clipboard, then go to Visual Studio, to some code file, and execute from menu: Edit, Paste Special, Paste XML as Classes."

    That indeed did work. But why is xsd.exe not generating a .cs code file with code that actually works? I do have various xsd.exe files on my system but I now tried a few of them and none produced code that works. Note that

    1) I run xsd as a pre-build event and I would like to keep it this way rather than using the manual special paste.

    2) Visual Studio 2015 does not find xsd if I don't define a path. Therefore, I had to search for xsd.exe and then in the pre-build event define an absolute path. I figured that maybe I pointed it to an xsd that is incompatible so I tried a few others without success. The issue is probably somewhere with an incompatible xsd but how do I find the right one and why do I have to define an absolute path in the first place?

    Sunday, December 17, 2017 6:34 AM
  • Hi hfaun,

    >>I run xsd as a pre-build event and I would like to keep it this way rather than using the manual special paste.

    Based on your description and related code, I create a simple console app and reproduce your issue on my side. As Viorel said, you need to replace ‘[][]’ with ‘[]’ in the generated class. if you don't want to replace it by manually, you could write a custom msbuild task to replace it.

    >>The issue is probably somewhere with an incompatible xsd but how do I find the right one and why do I have to define an absolute path in the first place?

    You could also get the path from registry, for more information, please refer to:

    https://stackoverflow.com/questions/14897750/automate-xsd-exe-during-build

    Best regards,

    Zhanglong Wu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, December 18, 2017 9:04 AM
    Moderator