tags:

views:

994

answers:

2

I have a rather detailed xml file. Below is the top level nodes (I have included the ellipse as the lower level nodes are all well formed and properly filled with data):

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <Models>...</Models>
    <Data>...</Data>
</config>

I have created an xsd file from using the Visual Studio 2008 command prompt:

xsd sample.xml

This generates the xsd file just fine. I then auto generate classes from the xsd with the command:

xsd sample.xsd /classes

For the deserialization of the xml file into a class object, I'm using the read function in the helper class:

public class XmlSerializerHelper<T>
{
    public Type _type;

    public XmlSerializerHelper()
    {
        _type = typeof(T);
    }

    public void Save(string path, object obj)
    {
        using (TextWriter textWriter = new StreamWriter(path))
        {
            XmlSerializer serializer = new XmlSerializer(_type);
            serializer.Serialize(textWriter, obj);
        }
    }

    public T Read(string path)
    {
        T result;
        using (TextReader textReader = new StreamReader(path))
        {
            XmlSerializer deserializer = new XmlSerializer(_type);
            result = (T)deserializer.Deserialize(textReader);
        }
        return result;
    }
}

When attempting the deserialization with:

var helper = new XmlSerializerHelper<configModels>();
var obj = new configModels();
obj = helper.Read(filepath);

I receive an error that I have deduced is because the deserializer is looking for the 'Models' node but the corresponding class name was generated as a combination of the root node and the 'Model' node (configModels). Why are the class names generated like this?

I tried to deserialize from the top node using:

var helper = new XmlSerializerHelper<config>();
var obj = new config();
obj = helper.Read(filepath);

Unfortunately, this the results in a slew of errors like the following:

System.InvalidOperationException was unhandled by user code
Message="Unable to generate a temporary class (result=1).
error CS0030: Cannot convert type 'Application.Lease[]' to 'Application.Lease'
error CS0030: Cannot convert type 'Application.CashFlow[]' to 'Application.CashFlow'
...ect.

Can somebody steer me towards what I might be doing wrong with my xsd auto-generating?

+2  A: 

There's an issue with xsd.exe and lists. You have to go into the generated class and manually edit the file to the correct type. I've switched to using Xsd2Code. So far it doesn't seem to have this problem.

John Kraft
I just tried Xsd2Code and it too is giving me the same conversion errors with the lists.
gun_shy
Should I not use xsd.exe to auto-generate the xsd file?
gun_shy
You can use it just fine. You simply have to go into the generated class and edit it by hand. However, if Xsd2Code had problems as well, I'd have to agree with @marc_s; it is probably something in your xml schema that is causing the problem.
John Kraft
Just tried Xsd2Code after a lot of problems with the other tool, and it worked great! Not correct directly but the errors were descriptive enough to resolve the whole thing within 5-10 minutes!
Gabriël
+2  A: 

XSD.EXE is a good start - but it's far from perfect. Also, based on the XML you provided, XSD.EXE can't always decide for sure whether something is a single instance of an object, or an open-ended array of objects.

This seems to be the case for your two elements - Application.Lease and Application.CashFlow. How are they defined in the generated XSD file? Does that make sense to you? Quite possibly, you'd have to add a little hints, such as:

<xs:element name="Lease" minOccurs="0" maxOccurs="1" />

for an optional property, that's zero or one occurences only. Things like that are really hard for the xsd.exe tool to figure out based on just a single XML sample file.

Marc

marc_s