我有一个类,当序列化为XML时看起来像这样(为简单起见而推广):
<root>
<resources>
<resource name="foo" anotherattribute="value">data</resource>
<resource name="bar" anotherattribute="value">more data</resource>
</resource>
<myobject name="objName">
<resource name="foo" />
</myobject>
</root>
当反序列化时,我需要在resource
实例的属性中引用的myobject
实例与在resources
集合的反序列化期间创建的对象相同。另外,如果可能的话,我不想在resource
中输出myobject
实例的完整序列化,只需输出名称。
有没有办法做到这一点?现在我正在考虑使用单独的字符串属性来进行序列化,当反序列化器设置属性时,它会从root
获取相关对象,但这意味着为myobject
提供对{{1}的引用包含它,我希望避免这种耦合。
答案 0 :(得分:1)
你不能用XmlSerializer
做到这一点,因为它不处理对象引用。
如果您对生成的架构没有任何约束,则可以使用DataContractSerializer
,它也序列化为XML但支持引用。要使用DataContractSerializer
,每种类型都必须具有DataContract
属性,并且您要序列化的每个成员都必须具有DataMember
属性:
[DataContract(Name = "root")]
public class root
{
[DataMember]
public List<resource> resources { get; set; }
[DataMember]
public myobject myobject { get; set; }
}
[DataContract]
public class myobject
{
[DataMember]
public string name { get; set; }
[DataMember]
public resource resource { get; set; }
}
[DataContract(Name = "resource", IsReference = true)]
public class resource
{
[DataMember]
public string name { get; set; }
[DataMember]
public string anotherattribute { get; set; }
[DataMember]
public string content { get; set; }
}
...
var serializer = new DataContractSerializer(typeof(root));
using (var xwriter = XmlWriter.Create(fileName))
{
serializer.WriteObject(xwriter, r);
}
请注意IsReference = true
类的resource
:这是使序列化程序通过引用处理此类的原因。在生成的XML中,每个resource
实例仅被序列化一次:
<?xml version="1.0" encoding="utf-8"?>
<root xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/">
<myobject>
<name>objName</name>
<resource z:Id="i1" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
<anotherattribute>value</anotherattribute>
<content>data</content>
<name>foo</name>
</resource>
</myobject>
<resources>
<resource z:Ref="i1" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" />
<resource z:Id="i2" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
<anotherattribute>value</anotherattribute>
<content>more data</content>
<name>bar</name>
</resource>
</resources>
</root>