views:

443

answers:

4

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?

+2  A: 

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.

Andrew Shepherd
Thanks, this has gotten me a lot closer, I'm still have issues getting data into the Subscription object, I've added details in the original post.
Aaron
I'm going to go ahead and accept this answer, it got me the closest. I found I can get the data in Json, so I'm using the Json.NET library to solve the deserialization problem. Thanks.
Aaron
A: 

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>
SwDevMan81
+1  A: 

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).

John Saunders
I agree, that XML would be easy to deserialize, however the XML I've been handed is from Google, you'd think they'd know better.
Aaron
@Aaron: no, I think they're not considering people who want to deserialize into an object. They may expect you to process the XML directly.
John Saunders
I was thinking there was something not right about that XML. Glad to know it wasn't just me.
Andrew Shepherd
A: 

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

HTH

unclepaul84
XSD didn't come up with anything usable, I think its due to the form of XML
Aaron