.NET XML序列化 - 存储引用,而不是对象的副本 [英] .net XML Serialization - Storing Reference instead of Object Copy

查看:163
本文介绍了.NET XML序列化 - 存储引用,而不是对象的副本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  • 在净/ C#应用程序,我有数据结构具有相互之间的引用。
  • 当我序列化它们,净序列化与独立的对象副本的所有引用。
  • 在以下示例中,我试图序列化到'人'
  • 数组
  • 人可能会参考其他人。

  • 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>

  • 在上面code,同样的'迈克'的对象是有两个地方,因为是同一个对象的两个引用。

    推荐答案

    这是不可能的<一个href="http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx">XmlSerializer.你可以做到这一点与<一个href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.aspx">DataContractSerializer使用<一个href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.$p$pserveobjectreferences.aspx">$p$pserveObjectReferences属性。你可以看看这个帖子这解释了细节。

    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.

    下面是一个示例code:

    Here's a sample code:

    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 在构造函数中,你会得到这样的:

    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的(同样的评论被反序列化的<一个href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatters.binary.binaryformatter.aspx">BinaryFormatter).

    这篇关于.NET XML序列化 - 存储引用,而不是对象的副本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆