C# 中列表的泛型序列化
本文关键字:泛型 序列化 列表 | 更新日期: 2023-09-27 18:31:24
我正在尝试将几个对象列表序列化为 xml。 列表的类型不同,但它们都需要在顶部列表对象上具有一些相同的属性。
我试图获得的是顶层的"计数"和列表中所有项目的对象名称:
<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 >
我已经尝试过这样的属性命名,但得到<_x007B_0_x007D_>而不是项目。
[XmlElement({0})]
public List<T> Items { get; set; }
动态命名项目的最佳方法是什么?
我最终解决这个问题的方法是以类似的方式创建结果类:
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; }
}
结果类中列表上的 [XmlIgnore ] 允许我使用 [XmlElement] 属性指定派生类中列表项的名称。
以下是您如何实现它的工作/人员类型
,定义如下public class Job
{
[XmlElement]
public int Id;
}
public class Person
{
[XmlElement]
public int Id;
}
到产品作业结果 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