XML 字符串反序列化为 c# 对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14722492/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 12:48:26  来源:igfitidea点击:

XML string deserialization into c# object

c#xml

提问by Darius V

I receive xml file like this.

我收到这样的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>

with many instances of programmeand channel. I try to deserialize it into this c# object but I get a null instead of object:

有许多programchannel实例。我尝试将它反序列化为这个 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;
    }
}

What am I doing wrong and what would be the proper xml object class?

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

采纳答案by sa_ddam213

You will just have to change you Radioclass a bit, since the 2 object types a mixed in the same array you will have to add some attributes to let the serializer know whats what.

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

[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()
    {
    }
}

Results:

结果:

enter image description here

在此处输入图片说明

回答by Anirudha

Use LINQ2XML

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

You can now iterate through channelLst

您现在可以遍历 channelLst

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