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>
In above code, the same 'Mike' object are there on two places, since there are two references for the same object.
XML Serialization Considerations Type identity and assembly information are not included. Only public properties and fields can be serialized. Properties must have public accessors (get and set methods). If you must serialize non-public data, use the DataContractSerializer class rather than XML serialization.
XML serialization can also be used to serialize objects into XML streams that conform to the SOAP specification. SOAP is a protocol based on XML, designed specifically to transport procedure calls using XML. To serialize or deserialize objects, use the XmlSerializer class.
XML serialization is the process of converting XML data from its representation in the XQuery and XPath data model, which is the hierarchical format it has in a Db2® database, to the serialized string format that it has in an application.
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.
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); } }
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>
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>
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).
You can use ExtendedXmlSerializer. Here is an example of serialization object reference and circular reference
If you have a class:
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public Person Boss { get; set; }
}
public class Company
{
public List<Person> Employees { get; set; }
}
then you create object with circular reference, like this:
var boss = new Person {Id = 1, Name = "John"};
boss.Boss = boss; //himself boss
var worker = new Person {Id = 2, Name = "Oliver"};
worker.Boss = boss;
var obj = new Company
{
Employees = new List<Person>
{
worker,
boss
}
};
You must configure Person class as reference object:
var serializer = new ConfigurationContainer().ConfigureType<Person>()
.EnableReferences(p => p.Id)
.Create();
In the end you can serialize your object:
var xml = serializer.Serialize(obj);
Output xml will look like this:
<?xml version="1.0" encoding="utf-8"?>
<Company xmlns="clr-namespace:ExtendedXmlSerializer.Samples.ObjectReference;assembly=ExtendedXmlSerializer.Samples">
<Employees>
<Capacity>4</Capacity>
<Person Id="2">
<Name>Oliver</Name>
<Boss Id="1">
<Name>John</Name>
<Boss xmlns:exs="https://extendedxmlserializer.github.io/v2" exs:entity="1" />
</Boss>
</Person>
<Person xmlns:exs="https://extendedxmlserializer.github.io/v2" exs:entity="1" />
</Employees>
</Company>
ExtendedXmlSerializer support .net 4.5 and .net Core.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With