C#中列表的通用序列化

时间:2012-04-16 02:09:27

标签: c# xml serialization generic-list

我正在尝试将几个对象列表序列化为xml。列表具有不同的类型,但它们都需要在顶部列表对象上具有一些相同的属性。

我想要得到的是顶层的'count'和列表中所有项目的对象名称:

 <JobResult Count="2">
       <Job>
           <Id>1</Id>
       </Job>
       <Job>
           <Id>2</Id>
       </Job>
    </JobResult>

然后换另一个清单:

 <PersonResult Count="1">
       <Person>
           <Id>1</Id>
       </Person>
 </PersonResult>

我使用的代码是:

[XmlRoot()]
    public class Result<T>
    {
        [XmlElement()]
        public List<T> Items { get; set; }

        public Result()
        {
            this.Items = new List<T>();
        }

        [XmlAttribute("Count")]
        public int ItemCount
        {
            get
            {
                return this.Items.Count;
            }
            set
            {

            }
        }
    }
var jobs= new Result<Job>();
var persons= new Result<Person>();

我得到的是:

<ResultOfJob Count="2">
       <Item>
           <Id>1</Id>
       </Item>
       <Item>
           <Id>2</Id>
       </Item>
    </ResultOfJob >

我尝试过这样的属性命名,但得到&lt; _x007B_0_x007D_&gt;而不是项目。

[XmlElement({0})]
 public List<T> Items { get; set; }

动态命名项目的最佳方法是什么?

2 个答案:

答案 0 :(得分:3)

我最终解决这个问题的方法是以类似的方式创建结果类:

public abstract class Result<T> 
{
    [XmlIgnore]
    public abstract List<T> Items {get;set;}

    [XmlAttribute]
    public int ResultCount
    {
        get
        {
            return this.Items.Count;
        }
        set { }
    }


    public Result()
    {
        this.Items = new List<T>();
    }

然后我为任何需要将公共ResultCount作为属性的对象继承此类。如果我需要向所有结果对象添加任何其他公共属性,我可以通过上面的Result类来完成。

这是一个继承类的示例:

public class ChallengesResult : Result<ChallengeResource>
{
    public ChallengesResult()
        : base()
    {
    }


    [XmlElement("Challenge")]
    public override List<ChallengeResource> Items { get; set; }
}

Result类中List上的[XmlIgnore]允许我使用[XmlElement]属性指定派生类中列表项的名称。

答案 1 :(得分:0)

以下是如何为下面定义的作业/人员类型实现它

public class Job
{
    [XmlElement]
    public int Id;
}

public class Person
{
    [XmlElement]
    public int Id;
}

生产JobResult Xml,

private static string GetJobResultXml()
{
    var jobs = new Result<Job>();
    jobs.Items.Add(new Job() { Id = 1 });
    jobs.Items.Add(new Job() { Id = 2 });

    XmlSerializerNamespaces xmlnsEmpty = new XmlSerializerNamespaces();
    xmlnsEmpty.Add("", "");

    XmlWriterSettings xws = new XmlWriterSettings();
    xws.OmitXmlDeclaration = true;
    xws.ConformanceLevel = ConformanceLevel.Auto;
    xws.Indent = true;

    XmlAttributeOverrides overrides = new XmlAttributeOverrides();
    XmlAttributes attr = new XmlAttributes();
    attr.XmlRoot = new XmlRootAttribute("JobResult");
    overrides.Add(jobs.GetType(), attr);

    XmlAttributes attr1 = new XmlAttributes();
    attr1.XmlElements.Add(new XmlElementAttribute("Job", typeof(Job)));
    overrides.Add(jobs.GetType(), "Items", attr1);

    StringBuilder xmlString = new StringBuilder();
    using (XmlWriter xtw = XmlTextWriter.Create(xmlString, xws))
    {
        XmlSerializer serializer = new XmlSerializer(jobs.GetType(), overrides);
        serializer.Serialize(xtw, jobs, xmlnsEmpty);

        xtw.Flush();
    }

    return xmlString.ToString();
}

为了生成PersonResult xml,您必须稍微修改上述方法以获得预期结果,如下所示

private static string GetPersonResultXml()
{
    var jobs = new Result<Person>();
    jobs.Items.Add(new Person() { Id = 1 });
    jobs.Items.Add(new Person() { Id = 2 });

    XmlSerializerNamespaces xmlnsEmpty = new XmlSerializerNamespaces();
    xmlnsEmpty.Add("", "");

    XmlWriterSettings xws = new XmlWriterSettings();
    xws.OmitXmlDeclaration = true;
    xws.ConformanceLevel = ConformanceLevel.Auto;
    xws.Indent = true;

    XmlAttributeOverrides overrides = new XmlAttributeOverrides();
    XmlAttributes attr = new XmlAttributes();
    attr.XmlRoot = new XmlRootAttribute("PersonResult");
    overrides.Add(jobs.GetType(), attr);

    XmlAttributes attr1 = new XmlAttributes();
    attr1.XmlElements.Add(new XmlElementAttribute("Person", typeof(Person)));
    overrides.Add(jobs.GetType(), "Items", attr1);

    StringBuilder xmlString = new StringBuilder();
    using (XmlWriter xtw = XmlTextWriter.Create(xmlString, xws))
    {
        XmlSerializer serializer = new XmlSerializer(jobs.GetType(), overrides);
        serializer.Serialize(xtw, jobs, xmlnsEmpty);

        xtw.Flush();
    }

    return xmlString.ToString();
}

我希望这会有所帮助。

有关使用XmlAttributes类的更多信息,请点击此链接

http://msdn.microsoft.com/en-us/library/sx1a4zea(v=vs.80).aspx