Billdr
Billdr

Reputation: 1579

Deserialize xml node's attributes to class

I have two classes that look like this:

[XmlRoot("Foo")]
public class Foo
{
    [XmlArray("BarResponse")]
    [XmlArrayItem("Bar")]
    public List<Bar> bar {get; set;}
    //some other elements go here.
}

[XmlRoot("Bar")]
public class Bar
{
    [XmlAttribute("id")]
    public Int32 Id {get; set;}
    //some other elements go here.
}

The xml I'm receiving looks like this:

<?xml version="1.0"?>
<Foo>
    <BarResponse>
        <Bar id="0" />
        <Bar id="1" />
    </BarResponse>
</Foo>

When I attempt to deseralize this, I get an instance of the "Foo" class, and bar has one element in it, with all of it's properties null or default. Where am I going wrong?

Upvotes: 1

Views: 6234

Answers (2)

Johan Larsson
Johan Larsson

Reputation: 17590

try this:

[TestFixture]
public class BilldrTest
{
    [Test]
    public void SerializeDeserializeTest()
    {
        var foo = new Foo();
        foo.Bars.Add(new Bar { Id = 1 });
        foo.Bars.Add(new Bar { Id = 2 });
        var xmlSerializer = new XmlSerializer(typeof (Foo));
        var stringBuilder = new StringBuilder();
        using (var stringWriter = new StringWriter(stringBuilder))
        {
            xmlSerializer.Serialize(stringWriter, foo);
        }
        string s = stringBuilder.ToString();
        Foo deserialized;
        using (var stringReader = new StringReader(s))
        {
            deserialized = (Foo) xmlSerializer.Deserialize(stringReader);
        }
        Assert.AreEqual(2,deserialized.Bars.Count);
    }
}

[XmlRoot("Foo")]
public class Foo
{
    public Foo()
    {
        Bars= new List<Bar>();
    }
    [XmlArray("BarResponses")]
    [XmlArrayItem(typeof(Bar))]
    public List<Bar> Bars { get; set; }
    //some other elements go here.
}

[XmlRoot("Bar")]
public class Bar
{
    [XmlAttribute("id")]
    public Int32 Id { get; set; }
    //some other elements go here.
}
  • You can find info on the use of XmlRoot here
  • ArrayItemAttribute is used if you expect the array to contain different types

You would get the same result stripping all attributes except for [XmlAttribute("id")], but I guess this is an excerpt from a context where it all is justified.

Upvotes: 1

Dave M
Dave M

Reputation: 1322

You need to add a default constructor for the Foo class that instantiates your List<Bar>.

[Serializable]
public class Foo
{
    public Foo()
    {
        Bar = new List<Bar>();
    }

    [XmlArray("BarResponse")]
    [XmlArrayItem("Bar")]
    public List<Bar> Bar { get; set; }
}

[Serializable]
public class Bar
{
    [XmlAttribute("id")]
    public Int32 Id { get; set; }
}

Writes/Reads xml as:

<?xml version="1.0" encoding="utf-8"?>
<Foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <BarResponse>
    <Bar id="0" />
    <Bar id="1" />
  </BarResponse>
</Foo>

Upvotes: 0

Related Questions