Serializing XML uncontained arrays in C#
I am working on an app that needs to deserialize a XML document that looks like this:
<results>
<item ...>
</item>
<item ...>
</item>
<item ...>
</item>
...
</results>
So I've set up an object model like this:
[XmlRoot("results")]
public class Results
{
[XmlArray("item")]
[XmlArrayItem("item", typeof(Item))]
public List<Item> Items { get; set; }
}
public class Item
{
[XmlElement("name")]
public string Name { get; set; }
[XmlElement("description")]
public string Description { get; set; }
. . .
}
I have tried many variations in how the Items c开发者_StackOverflow社区ollection is declared and annotated, but regardless I never get any items in that collection. Are there issues in .NET around deserializing arrays that are not contained within a common parent element (i.e., what might be in this example)?
I do not have control over the format of this XML so I have to make it work as is. I am currently using XDocument/XElement/XAttribute to read and parse the XML manually, but that's a pain. Any ideas why this isn't working?
Thanks in advance.
A little known secret seems to be the XSD.exe utility that ships with Visual Studio. Among other things it can do, two features you will need:
Generate an XSD from an XML file
c:\>xsd myfile.xml
This will infer an XSD from your XML and spit it out on disk. Which you can then take and:
Generate a C# class from the XSD file
c:\>xsd myfile.xsd /classes
This will generate a series of C# classes with all the necessary serialization attributes on them. You don't have to use them directly, but you could certainly figure out how what .Net is expecting.
My first step when doing such a job, is to create some sample instances and to serialize them. If the output fits your xml, your ready to read it back. That's usually the most simple way to get all pices together. But arrays, lists, ... are sometimes really tricky. If you are forced to have a certain schema, it's sometimes helpful to implement ISerializable for some parts of your classes. That way you can fine tune criticial pices but have the luxury of default xml serialization for other parts.
With respect to the example xml content you provided in your question, this will do it:
[XmlRoot("results")]
public class Results
{
[XmlElement("item")]
public List<Item> Items { get; set; }
}
It covers the case where there is no outer element, as may be named "items" for example.
精彩评论