C#中列表的通用序列化

3
我正在尝试将多个对象列表序列化为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 >

我尝试了这种属性命名,但是得到的不是item而是<_x007B_0_x007D_>。
[XmlElement({0})]
 public List<T> Items { get; set; }

什么是处理动态命名项目的最佳方法?
2个回答

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

然后我会继承这个类,用于任何需要将common ResultCount作为属性的对象。如果我需要向所有结果对象添加其他共同属性,可以通过上面的Result类来实现。

下面是一个示例继承类:

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


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

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


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


这似乎可以得到所需的结果,但它似乎不能动态地执行。如果我想要序列化每个新对象,我必须编写一个函数。 - jsturtevant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接