反序列化XML

时间:2011-04-20 21:05:18

标签: .net xml serialization deserialization

我正在尝试使用以下xml和类反序列化某些xml。我遇到的问题是xml元素名称与我想用于我的类的名称不匹配。我试图使用XmlRoot指定元素名称,但无法使其工作。任何帮助将不胜感激。

  

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

[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;
    }

4 个答案:

答案 0 :(得分:1)

假设您已修复格式并拥有有效的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>

以下应该可以正常工作:

[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
        }
    }
}

答案 1 :(得分:0)

XmlSerializer有一个构造函数,它接受要使用的根标记。这应该有所帮助。我总是会创建我的类的一些示例实例,并将序列化这些实例。这样就可以很容易地弄清楚如何微调xml序列化/反序列化。

答案 2 :(得分:0)

除了尝试手动推断属性之外,.Net SDK的一个鲜为人知的功能是xsd.exe可以为您完成工作。在.Net命令提示符中输入:

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

它将为该架构创建正确的序列化类。如果您没有架构,可以让xsd.exe为您生成一个架构。只需传递一个示例xml文件,就像您提供的一个参数一样,它将生成相应的xsd文件。

生成的类是部分的,因此您可以扩展它们,而不必在重新生成它们时重新应用所有更改。

除了“/ classes”之外,还有其他可能派上用场的开关,例如“/ ebd”,它生成实现INotifyPropertyChanged的类,或“/ fields”,它生成简单的字段而不是属性。

答案 3 :(得分:0)

[XmlRoot]仅在将类用作文档的根元素时使用。要指定一般使用的元素名称,请使用[XmlType]