开发者

Deserializing XML

I am trying to deserialize some xml using the following xml and classes. The issue that I am running into is that the xml element names do not match the names I'd like to use for my classes. I have attempted to use XmlRoot to specify an element name, but have not been able to get it to work. Any help would be appreciated.

<Results recordReturn="3" xmlns="http://www.zzz.com/"> <Result> <key>98937747-0596-42e6-aa5b-e180d35f649e</key> <code>AFGHANISTAN</code> <number>004</number> </Result> <Result> <key>100ab860-f2a5-48ed-911c-31753b79234f</key> <code>ALBANIA开发者_如何学C</code> <number>008</number> </Result> <Result> <key>67ecc235-d44a-41e0-b2a0-7a9c00e30a0e</key> <code>ALGERIA</code> <number>012</number> </Result>

[Serializable]
[XmlRoot("Result", Namespace = "http://www.zzz.com/")]    
public class Country
{
    public Country()
    { }

    public string key;
    public string code;
    public string number;
}

[Serializable]
[XmlRoot(ElementName = "Results", Namespace = "http://www.zzz.com/")]
public class Countries : System.Collections.CollectionBase
{
    public Country this[int nIndex]
    {
        get { return (Country)this.InnerList[nIndex]; }
    }

    public void Add(Country oCountry)
    {
        this.List.Add(oCountry);
    }
}


//Code below is in separate class file
    public static Countries GetAllCountries()
    {
        XmlNode countriesNode = //omitting code to get country xml
        Countries countryList = new Countries();
        XmlSerializer serializer = new XmlSerializer(typeof(Countries));
        System.Xml.XmlNodeReader oReader = new System.Xml.XmlNodeReader(countriesNode);
        countryList = (Countries)serializer.Deserialize(oReader);

        return countryList;
    }


Assuming you have fixed your formatting and have a valid XML:

<Results recordReturn="3" xmlns="http://www.zzz.com/">
  <Result>
    <key>98937747-0596-42e6-aa5b-e180d35f649e</key>
    <code>AFGHANISTAN</code>
    <number>004</number>
  </Result>
  <Result>
    <key>100ab860-f2a5-48ed-911c-31753b79234f</key>
    <code>ALBANIA</code>
    <number>008</number>
  </Result>
  <Result>
    <key>67ecc235-d44a-41e0-b2a0-7a9c00e30a0e</key>
    <code>ALGERIA</code>
    <number>012</number>
  </Result>
</Results>

The following should work just fine:

[XmlRoot("Result")]
public class Country
{
    [XmlElement("key")]
    public string Key { get; set; }
    [XmlElement("code")]
    public string Code { get; set; }
    [XmlElement("number")]
    public string Number { get; set; }
}

public class Results
{
    [XmlAttribute("recordReturn")]
    public int RecordReturn { get; set; }

    [XmlElement("Result")]
    public Country[] Countries { get; set; }
}

class Program
{
    static void Main()
    {
        var serializer = new XmlSerializer(typeof(Results), "http://www.zzz.com/");
        using (var reader = XmlReader.Create("test.xml"))
        {
            var results = (Results)serializer.Deserialize(reader);
            // TODO : exploit the results
        }
    }
}


XmlSerializer has an constructor which accepts the root tag to be used. That should help. I would always create some samples instances of my classes and would serialize those. That way it's very easy to figure out how to fine tune xml serialization / deserialization.


Apart from trying to infer the attributes manually, a less known feature of the .Net SDK is that xsd.exe can do the work for you. In a .Net command prompt just type:

xsd.exe <name of your schema>.xsd /classes

It will create the correct serialization classes for that schema. If you don't have a schema you can let xsd.exe generate one for you. Simply pass it a sample xml file like the one you provided as an argument, and it will produce the corresponding xsd file.

The classes generated are partial, so you could extend them without having to reapply all your changes if you happen to regenerate them.

Apart from "/classes" there are others switches which might come in handy, such as "/ebd", which produces classes that implement INotifyPropertyChanged, or "/fields", which generates simple fields instead of properties.


[XmlRoot] is only used when the class is used as the root element of the document. To specify the element name to be used in general, use [XmlType].

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜