.net XML 序列化 - 存储引用而不是对象副本 [英] .net XML Serialization - Storing Reference instead of Object Copy
问题描述
- 在 .Net/C# 应用程序中,我有相互引用的数据结构.
- 当我序列化它们时,.Net 使用单独的对象副本序列化所有引用.
- 在以下示例中,我尝试序列化为人"数组
一个人"可能会引用另一个人.
- In .Net/C# Application, I have data structures which have references to each other.
- When I serialize them, .Net Serializes all references with separate object copies.
- In Following Example, I am trying to serialize to Array of 'Person'
A 'Person' may have reference to another person.
public class Person
{
public string Name;
public Person Friend;
}
Person p1 = new Person();
p1.Name = "John";
Person p2 = new Person();
p2.Name = "Mike";
p1.Friend = p2;
Person[] group = new Person[] { p1, p2 };
XmlSerializer ser = new XmlSerializer(typeof(Person[]));
using (TextWriter tw = new StreamWriter("test.xml"))
ser.Serialize(tw,group );
//above code generates following xml
<ArrayOfPerson>
<Person>
<Name>John</Name>
<Friend>
<Name>Mike</Name>
</Friend>
</Person>
<Person>
<Name>Mike</Name>
</Person>
</ArrayOfPerson>
在上面的代码中,同一个Mike"对象出现在两个地方,因为同一个对象有两个引用.
推荐答案
XmlSerializer.您可以通过 DataContractSerializer 使用PreserveObjectReferences 属性.你可以看看这个 post ,它解释了详情.
It is not possible with XmlSerializer. You could achieve this with DataContractSerializer using the PreserveObjectReferences property. You may take a look at this post which explains the details.
这是一个示例代码:
public class Person
{
public string Name;
public Person Friend;
}
class Program
{
static void Main(string[] args)
{
Person p1 = new Person();
p1.Name = "John";
Person p2 = new Person();
p2.Name = "Mike";
p1.Friend = p2;
Person[] group = new Person[] { p1, p2 };
var serializer = new DataContractSerializer(group.GetType(), null,
0x7FFF /*maxItemsInObjectGraph*/,
false /*ignoreExtensionDataObject*/,
true /*preserveObjectReferences : this is where the magic happens */,
null /*dataContractSurrogate*/);
serializer.WriteObject(Console.OpenStandardOutput(), group);
}
}
这会生成以下 XML:
This produces the following XML:
<ArrayOfPerson z:Id="1" z:Size="2" xmlns="http://schemas.datacontract.org/2004/07/ToDelete" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
<Person z:Id="2">
<Friend z:Id="3">
<Friend i:nil="true"/>
<Name z:Id="4">Mike</Name>
</Friend>
<Name z:Id="5">John</Name>
</Person>
<Person z:Ref="3" i:nil="true"/>
</ArrayOfPerson>
现在在构造函数中将 PreserveObjectReferences
设置为 false
,您将得到:
Now set PreserveObjectReferences
to false
in the constructor and you will get this:
<ArrayOfPerson xmlns="http://schemas.datacontract.org/2004/07/ToDelete" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Person>
<Friend>
<Friend i:nil="true"/>
<Name>Mike</Name>
</Friend>
<Name>John</Name>
</Person>
<Person>
<Friend i:nil="true"/>
<Name>Mike</Name>
</Person>
</ArrayOfPerson>
值得一提的是,这种方式生成的 XML 不能互操作,只能使用 DataContractSerializer 进行反序列化(与 BinaryFormatter).
It is worth mentioning that the XML produced this way is not interoperable and can only be deserialized with a DataContractSerializer (same remark as with the BinaryFormatter).
这篇关于.net XML 序列化 - 存储引用而不是对象副本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!