如何设计和装饰 class(es) 以便我可以反序列化以下 xml?

How to design and decorate class(es) so I can deserialize following xml?

我想将以下 xml 反序列化为自定义 class:

<?xml version="1.0" encoding="ISO-8859-1"?>
<rss version="2.0">
<channel>
 <title>test</title>
 <description>test</description>
 <language>nl</language>
 <link>http://www.test.test</link>
 <item>
  <link>http://www.testlink1</link>
  <pubDate>Di, 03 Nov 2015 09:08:44 +0100</pubDate>
  <sector>
   <entry>a:b</entry>
   <entry>a:c</entry>
   <entry>a:d</entry>
   <entry>a:b</entry>
  </sector>
  <title>test</title>
  <lead><![CDATA[test]]></lead>
  <description><![CDATA[test ]]></description>
  <images>
   <enclosure url="http://test.dll?tem=LTO_IMAGE_DOC&amp;size=1024&amp;doc_id=100782" length="608055" type="image/jpg"/>
  </images>
 </item>
</channel>
</rss>

这是我的 class :

    [Serializable]
    [XmlRoot("item", IsNullable = false)]
    public class CustomRssItem : BaseRssItem
    {
        [XmlElement("publisher", Namespace = "http://purl.org/dc/elements/1.1/")]
        public string Author { get; set; }

        [XmlElement("guid", Namespace = "")]
        public string Guid { get; set; }

        [XmlArray("sector")]
        [XmlArrayItem("entry")]
        public List<string> Sector { get; set; }

    }

如何修改我的 class 以使用自定义 class 而不是 List<string> 以便我可以包含我需要对入口元素执行的解析(将字符串与冒号分开)?

而不是 List<string> 我想写的扇区 List<GroupEntry> GroupEntry 将是我的自定义 class 包含值 "a:b" 的扇区,我可以解析并公开新属性,例如组和子组?

这就是我的建议

  1. 从 XML 文件创建 XSD
  2. 来自 XSD Create Class for it

下面是生成的Class,现在基于这个class你可以调整你的class或者直接使用下面的class。您还可以重命名属性并通过使用适当的属性装饰它们来自定义所有名称。

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.42000
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System.Xml.Serialization;

// 
// This source code was auto-generated by xsd, Version=4.6.81.0.
// 


/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.81.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class rss {

    private rssChannel channelField;

    private decimal versionField;

    /// <remarks/>
    public rssChannel channel {
        get {
            return this.channelField;
        }
        set {
            this.channelField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public decimal version {
        get {
            return this.versionField;
        }
        set {
            this.versionField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.81.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class rssChannel {

    private string titleField;

    private string descriptionField;

    private string languageField;

    private string linkField;

    private rssChannelItem itemField;

    /// <remarks/>
    public string title {
        get {
            return this.titleField;
        }
        set {
            this.titleField = value;
        }
    }

    /// <remarks/>
    public string description {
        get {
            return this.descriptionField;
        }
        set {
            this.descriptionField = value;
        }
    }

    /// <remarks/>
    public string language {
        get {
            return this.languageField;
        }
        set {
            this.languageField = value;
        }
    }

    /// <remarks/>
    public string link {
        get {
            return this.linkField;
        }
        set {
            this.linkField = value;
        }
    }

    /// <remarks/>
    public rssChannelItem item {
        get {
            return this.itemField;
        }
        set {
            this.itemField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.81.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class rssChannelItem {

    private string linkField;

    private string pubDateField;

    private string[] sectorField;

    private string titleField;

    private string leadField;

    private string descriptionField;

    private rssChannelItemImages imagesField;

    /// <remarks/>
    public string link {
        get {
            return this.linkField;
        }
        set {
            this.linkField = value;
        }
    }

    /// <remarks/>
    public string pubDate {
        get {
            return this.pubDateField;
        }
        set {
            this.pubDateField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlArrayItemAttribute("entry", IsNullable=false)]
    public string[] sector {
        get {
            return this.sectorField;
        }
        set {
            this.sectorField = value;
        }
    }

    /// <remarks/>
    public string title {
        get {
            return this.titleField;
        }
        set {
            this.titleField = value;
        }
    }

    /// <remarks/>
    public string lead {
        get {
            return this.leadField;
        }
        set {
            this.leadField = value;
        }
    }

    /// <remarks/>
    public string description {
        get {
            return this.descriptionField;
        }
        set {
            this.descriptionField = value;
        }
    }

    /// <remarks/>
    public rssChannelItemImages images {
        get {
            return this.imagesField;
        }
        set {
            this.imagesField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.81.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class rssChannelItemImages {

    private rssChannelItemImagesEnclosure enclosureField;

    /// <remarks/>
    public rssChannelItemImagesEnclosure enclosure {
        get {
            return this.enclosureField;
        }
        set {
            this.enclosureField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.81.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class rssChannelItemImagesEnclosure {

    private string urlField;

    private uint lengthField;

    private string typeField;

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string url {
        get {
            return this.urlField;
        }
        set {
            this.urlField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public uint length {
        get {
            return this.lengthField;
        }
        set {
            this.lengthField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string type {
        get {
            return this.typeField;
        }
        set {
            this.typeField = value;
        }
    }
}

通过使用正确的 XmlSerialization 属性实现 GroupEntry class,我们可以实现该目标。

class 将有 a 和 b 字段,但您不希望这些字段被序列化,因此我们在序列化期间使用 XmlIgnore 属性忽略它们

然后我们有一个 ab 字段,我们要将其序列化为元素文本。我们通过使用 XmlText 属性来实现这一点。

我们不仅为 ab 实现了 getter,而且还实现了 setter,因为当您从 xml.

这是所需的 GroupEntry class 代码:

public class GroupEntry
{
    [System.Xml.Serialization.XmlIgnore]
    public string a;
    [System.Xml.Serialization.XmlIgnore]
    public string b;

    [System.Xml.Serialization.XmlText]
    public string ab
    {
        get
        {
            return string.Format("{0}:{1}", a, b);
        }
        set
        {
            a = null;
            b = null;
            if (value != null)
            {
                string[] split = value.Split(':');
                a = split[0];
                if (split.Length > 1)
                {
                    b = split[1];
                }
            }
        }
    }
}