Question

I'm a bit out of my element. I've used xsd.exe to create an xsd schema from an xml file, and then to create a C# class from that xsd. That all seems to work fine.

At the moment I'm just trying to get the XML deserialized. The file I'm deserializing if the very same file I used to build the class originally. Here's my code:

String xsdPath=@"C:\Users\tol56881\Documents\dnd4e.xsd";
String xmlPath=@"C:\Users\tol56881\Documents\dnd4e.xml";
String xsdNamespace="";

//Validation stuff
XmlParserContext context = new XmlParserContext(null, null, "", XmlSpace.None);
XmlValidatingReader vr = new XmlValidatingReader(xmlPath, XmlNodeType.Element, context);
vr.ValidationType = ValidationType.Schema;
vr.Schemas.Add(xsdNamespace, xsdPath);
while (vr.Read()) ;

//Actually reading the file
TextReader tr = new StreamReader(xmlPath);
D20Character character = (D20Character)(new XmlSerializer(typeof(D20Character))).Deserialize(tr);

It compile fine, but when I try to run it I get the an error that's repeated for four different objects. I've given an example below, changing the names of the objects.

Unable to generate a temporary class (result=1).
error CS0030: Cannot convert type 'Namespace.ObjectName[]' to 'Namespace.ObjectName'
error CS0029: Cannot implicitly convert type 'Namespace.ObjectName' to 'Namespace.ObjectName[]'

So it seems like the program is trying to go from array to object and back to array, but I'm not really sure. The auto-generated class code is a huge mess that's difficult to wade through. I'm hoping that maybe there's something simple I'm missing here.

Thanks!

Was it helpful?

Solution

I managed to fix this. Each of the four objects in question were generated as doubly-indexed arrays, such as:

    private loot[][] lootTallyField;

and

    public loot[][] LootTally
    {
        get
        {
            return this.lootTallyField;
        }
        set
        {
            this.lootTallyField = value;
        }
    }

All I did was remove one set of brackets, and it all seems to be working fine. No problems with deserialization and a quick inspection of the deserialized object makes it look like the data was loaded correctly.

    private loot[] lootTallyField;

and

    public loot[] LootTally
    {
        get
        {
            return this.lootTallyField;
        }
        set
        {
            this.lootTallyField = value;
        }
    }

Still not sure why xsd.exe made these doubly-indexed if they're not supposed to be. I feel like I'm still missing something, hence why this question is still open.

Particularly, if I ever need to re-generate this code, then I'd need to reapply the fix, which kind of defeats the purpose of using a partial class in the first place...

OTHER TIPS

There is a problem on xsd.exe tool, I will try to explain.

If you have a complexType with a sequence inside that has a child complexType with a sequence and the first one does not have any other elements / attributes, then the generated class will have only 1 generated type, instead of 2 and it will be a double array.

If you make the double array into a single array, you will be able to deserialize your xml just fine. HOWEVER this will produce the following unexpected result. If your xml looks like the below.

<root>
    <loot>
        <tally>value1</tally>
        <tally>value2</tally>
    </loot>
    <loot>
        <tally>value3</tally>
        <tally>value4</tally>
    </loot>
</root>

Then your deserialized object, in the lootTally array would only contain the value3 and value4 items instead of having all 4.

So you have 2 options to fix this correctly:

  1. Alter the xsd file by adding a dummy in the first sequence, and run xsd.exe again, so that when it generates the class it will not create a double array, and then you can delete the dummy attribute from the class.
  2. Alter the generated class, add a new class named loot which will contain an array of tally objects which you already have (and only need to alter the name).

Please note that in option 2 you may have to change some declarations if you have an XmlArrayItemAttribute to XmlElementAttribute.

Hope this helps

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top