Aaron
Aaron

Reputation: 387

Deserializing difficultly formed XML to C# object

I have XML that is returned by a 3rd party web service in the following form:

<object>
    <list name="subscriptions">
        <object>
            <string name="id">something</string> 
            <string name="title">something else</string> 
            <list name="categories" /> 
            <number name="timestamp">1252707770116</number> 
        </object>
        ...more 'object'...
    </list>
</object>

I'm having a lot of issues trying to deserialize this data to an object. I wasn't able to generate a schema using xsd.exe, so I generated the following classes by hand to try and fit this data:

[XmlRoot("object")]
public class ListOfSubscriptions
{
    [XmlElement("list")]
    public Subscription[] items;
}

[XmlRoot("object")]
public class Subscription
{
    [XmlAttribute()]
    public string id;
    [XmlAttribute()]
    public string title;
    [XmlAttribute()]
    public string[] categories;
    [XmlAttribute()]
    public string timestamp;
}

I'm trying to deserialize this with the following code:

XmlSerializer s = new XmlSerializer(typeof(ListOfSubscriptions));
StreamReader r = new StreamReader("out.xml");
ListOfSubscriptions listSubscribe = (ListOfSubscriptions)s.Deserialize(r);
r.Close();

However, when it finishes, listSubscribe has one member and all its fields are null.

How should I be creating my template for deserializing?

Thanks

Update - 2010/01/28

Thanks to everybody's comments I've revised my classes to the following:

[XmlRoot("object")]
public class ListOfSubscriptions
{
    [XmlElement("list")]
    public SubscriptionList[] items;
}
[XmlRoot("list")]
public class SubscriptionList
{
    [XmlElement("object")]
    public Subscription[] items;
}

[XmlRoot("object")]
public class Subscription
{
    [XmlElement("string")]
    public string id;
    [XmlElement("string")]
    public string title;
    [XmlElement("list")]
    public string[] categories;
    [XmlElement("number")]
    public string timestamp;
}

If I comment out the [XmlElement(...)] lines in Subscription, and run, I get that listSubscribe has one SubscriptionList item which has the correct number of Subscriptions, however, all the elements of the subscriptions are null.

If I uncomment the XmlElement lines, I get an error reflecting a Subscription. I imagine its getting confused because there are multiple elements with the same name.

How do I tie the attribute name to the class member?

Upvotes: 2

Views: 2140

Answers (4)

unclepaul84
unclepaul84

Reputation: 1404

I believe you can use XSD.exe .Net framework utility to generate a class that can be used a memory representation of your XML document.

Upvotes: 0

John Saunders
John Saunders

Reputation: 161773

You're never going to get anywhere with XML like this:

<string name="id">something</string>  

That's just created by someone who doesn't know XML. The equivalent:

<id>something</id>

would be easy to deserialize.


The only way I can think of for you to deserialize that is by implementing the IXmlSerializable interface on your class(es).

Upvotes: 2

SwDevMan81
SwDevMan81

Reputation: 49978

You will want to change out XmlArry and XMLArrayItem.

Here is an example. It should look something like this:

[XmlArray("FullNames")]
[XmlArrayItem("Name")]
public string[] Names{get;set;}

will give you

<FullNames>
    <Name>Michael Jackson</Name>
    <Name>Paris Hilton</Name>
</FullNames>

Upvotes: 0

Andrew Shepherd
Andrew Shepherd

Reputation: 45232

You're on the right track. However, you are only defining two classes. There are actually three classes to define:

  1. The single root object, with an XML name of "object". This will have only one member:
  2. The list of objects (with an XML name of "list"). This will have one member, an array of:
  3. Subscriptions, with an XML name of "object".

Another problem is that you are defining the Subscription fields as attributes. They aren't attributes, they're elements.

Upvotes: 4

Related Questions