views:

585

answers:

5

I'm trying to create a class which I can serialize to produce the following XML:

<chart palette='1'>
  <categories>
    <category label='2001' />
    <category label='2002' />

..etc

I have a class which look something like this:

[XmlRoot("chart")]
public class Chart
{        
    [XmlAttributeAttribute("palette")]
    public string Palette;

    [XmlElement("categories")]
    public List<Category> Categories = new List<Category>();
}

[XmlRoot("category")]
public class Category
{
    [XmlAttributeAttribute("label")]
    public string Label;
}

However, this does not produce the desired chart->categories->category@label structure. The XmlRoot on the Category class doesn't seem to be used. Here is the output I have from that code:

 <chart palette="2">
  <categories label="2002" /> 
 </chart>

How can I get the XML structure I want?

A: 

A shot in the dark: Make category an XmlElement instead of root?

Luis
I get it, my idea stunk. Please refrain from adding more negatives to my score. Thanks!
Luis
+6  A: 

Use XmlArrayAttribute and XmlArrayItemAttribute

[XmlRoot("chart")]
public class Chart
{        
    [XmlAttributeAttribute("palette")]
    public string Palette;

    [XmlArray("categories")]
    [XmlArrayItem("category")]
    public List<Category> Categories = new List<Category>();
}


public class Category
{
    [XmlAttributeAttribute("label")]
    public string Label;
}

Sometimes is can be useful to just create the xml structure you want, and then use xsd.exe to generate classes from it. This has to be done in a 2-step process, first generating an xsd file, and then classes from that.

xsd.exe something.xml
xsd.exe something.xsd /classes

This will probably not give the exact result you want (unless you have a really good xsd, and don't just generate it from the xml), but does give some ideas

Sander Rijken
Thanks, it works! You have basically the same answer as Grzenio, but got the accepted answer because you had extra info.
Frode Lillerud
+4  A: 

Should be:

[XmlRoot("chart")]
public class Chart
{        
    [XmlAttributeAttribute("palette")]
    public string Palette;

    [XmlArray("categories")]
    [XmlArrayItem("category")]
    public List<Category> Categories = new List<Category>();
}

[XmlRoot("category")]
public class Category
{
    [XmlAttribute("label")]
    public string Label;
}
Grzenio
A: 

Even though this is for ASP.NET, you may find this link useful

XML Serialization in ASP.NET

It tell you how you can work both ways when it comes to serialization.

Also,dont forget the xsd.exe tool you can use via the command promt which comes with Visual Studio (I used .NET 2005)

For example, you could create the following schema by passing your XML file to it

e.g. xsd yourfile.xml

You can then use the xsd generated to create a serialization class, which is basically an object model of the XML with a class for each node by passing the schema to xsd

e.g. xsd yourfile.xsd /c /l:C

Again, this is based around .NET so apologies if this is not of interest to the original poster.

kevchadders
+1  A: 

I had a similar idea and wound up writing a custom base class to handle it. Check out my write up at http://www.ideosity.com/ASP-NET/Object-to-XML-lab.aspx. I think it will get you heading in the right direction.