【问题标题】:XML string deserialization into c# objectXML字符串反序列化为c#对象
【发布时间】:2013-02-06 05:54:33
【问题描述】:

我收到这样的 xml 文件。

<radio>
  <channel id="Opus">
    <display-name>Opus</display-name>
    <icon src="" />
  </channel>
  <channel id="Klasika">
    <display-name>Klasika</display-name>
    <icon src="" />
  </channel>
  <channel id="LR">
    <display-name>LR</display-name>
    <icon src="" />
  </channel>
  <programme channel="Opus" start="20130203060000" stop="20130203110000" duration="050000">
    <title lang="lt">OPUS muzika.</title>
    <desc lang="lt">OPUS muzika.</desc>
    <category lang="lt">muzikos laidos</category>
    <date>2013.02.03</date>
  </programme>
  <programme channel="Opus" start="20130203110000" stop="20130203150000" duration="040000">
    <title lang="lt">Vėlyvi pusryčiai su OPUS.</title>
    <desc lang="lt">Vėlyvi pusryčiai su OPUS.</desc>
    <category lang="lt">muzikos laidos</category>
    <date>2013.02.03</date>
  </programme>
</radio>

节目频道的许多实例。我尝试将它反序列化为这个 c# 对象,但我得到一个 null 而不是对象:

[XmlRoot("radio")]
public sealed class radio
{
    [XmlRoot("channel")]
    public sealed class channel
    {
        [XmlAttribute("id")]
        public string id { get; set; }

        [XmlElement("display-name")]
        public string displayName { get; set; }

        [XmlElement("icon")]
        public string icon { get; set; }

        public channel()
        {    
        }
    }

    [XmlRoot("programme")]
    public sealed class programme
    {
        [XmlAttribute("channel")]
        public string channel { get; set; }

        [XmlAttribute("start")]
        public string start { get; set; }

        [XmlAttribute("stop")]
        public string stop { get; set; }

        [XmlAttribute("duration")]
        public string duration { get; set; }

        [XmlElement("title")]
        public string title { get; set; }

        [XmlElement("desc")]
        public string desc { get; set; }

        [XmlElement("category")]
        public string category { get; set; }

        [XmlElement("date")]
        public string date { get; set; }

        public programme()
        {
        }
    }

    [XmlArray]
    public channel[] channels { get; set; }

    [XmlArray]
    public programme[] programmes { get; set; }

    public radio()
    {
        channels = null;
        programmes = null;
    }

    public static radio FromXmlString(string xmlString)
    {
        var reader = new StringReader(xmlString);
        var serializer = new XmlSerializer(typeof(radio));
        var instance = (radio)serializer.Deserialize(reader);

        return instance;
    }
}

我做错了什么,正确的 xml 对象类是什么?

【问题讨论】:

    标签: c# xml


    【解决方案1】:

    您只需稍微更改Radio 类,因为这两种对象类型混合在同一个数组中,您必须添加一些属性让序列化程序知道是什么。

    [XmlRoot("radio")]
    public sealed class radio
    {
        [XmlElement("channel", Type = typeof(channel))]
        public channel[] channels { get; set; }
    
        [XmlElement("programme", Type = typeof(programme))]
        public programme[] programmes { get; set; }
    
        public radio()
        {
            channels = null;
            programmes = null;
        }
    
        public static radio FromXmlString(string xmlString)
        {
            var reader = new StringReader(xmlString);
            var serializer = new XmlSerializer(typeof(radio));
            var instance = (radio)serializer.Deserialize(reader);
    
            return instance;
        }
    }
    
    [Serializable]
    public class channel
    {
        [XmlAttribute("id")]
        public string id { get; set; }
    
        [XmlElement("display-name")]
        public string displayName { get; set; }
    
        [XmlElement("icon")]
        public string icon { get; set; }
    
        public channel()
        {
        }
    }
    
    
    [Serializable]
    public sealed class programme
    {
        [XmlAttribute("channel")]
        public string channel { get; set; }
    
        [XmlAttribute("start")]
        public string start { get; set; }
    
        [XmlAttribute("stop")]
        public string stop { get; set; }
    
        [XmlAttribute("duration")]
        public string duration { get; set; }
    
        [XmlElement("title")]
        public string title { get; set; }
    
        [XmlElement("desc")]
        public string desc { get; set; }
    
        [XmlElement("category")]
        public string category { get; set; }
    
        [XmlElement("date")]
        public string date { get; set; }
    
        public programme()
        {
        }
    }
    

    结果:

    【讨论】:

    • 确保每个元素/数组/属性只装饰一次
    【解决方案2】:

    使用LINQ2XML

    XElement doc=XElement.Load("yourXML.xml");
    var channelLst=doc.Elements("channel").Select(x=>
    new
    {
        id=x.Attribute("id").Value,
        displayName=x.Element("display-name").Value,
        icon=x.Element("icon").Attribute("src").Value
    }
    );
    

    您现在可以遍历 channelLst

    foreach(var c in channelLst)
    {
        c.id;
        c.displayName;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-29
      • 1970-01-01
      • 1970-01-01
      • 2023-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多