- Classes must be public
- Classes must have parameterless constructors
- Properties must have public setters
- [Nonserializable] attribute does nothing
- Base classes need to have the XmlInclude attribute with their superclass types
//for xml
serialization class must be public
//base
classes need to have teh XmlInclude attribute
//with
any superclass types that inherit from them
[XmlInclude(typeof(Employee))]
[Serializable]
public class Person
{
//for xml serialization,
all properties must have public setters
public string
FirstName { get; set; }
public string LastName
{ get; set; }
public Person() { }
public Person(string
FirstName, string LastName)
{
this.FirstName = FirstName;
this.LastName = LastName;
}
public string FullName
{ get { return $"{FirstName} {LastName}"; } }
}
[Serializable]
public class Employee : Person
{
static int
_runningId;
public int Id { get;
set; } = _runningId++;
public string Wage { get; set; } = null;
public Employee() { }
public Employee(string
FirstName, string LastName) : base(FirstName, LastName) { }
}
now as you can see the marking classes as xml serialize-able is exactly the same as it was for binary serialization. as for the actual serialization and de-serialization.
class Program
{
static void Main(string[] args)
{
var ppl = new Person[] { new Person("John", "Smith"), new Person("Jane","Doe"),
new Employee("Sally","Johnson"),new Person("Alejandro", "Cruz"),
new Person("Diago","Pendaz"), new Employee("Tim","Chan")};
var xmlSerializer = new XmlSerializer(ppl.GetType());
using (var fs = new FileStream("c:/ppl.xml", FileMode.Create, FileAccess.Write))
xmlSerializer.Serialize(fs, ppl);
Person[] People;
using (var fs = new FileStream("c:/ppl.xml", FileMode.Open, FileAccess.Read))
People =
xmlSerializer.Deserialize(fs) as Person[];
foreach (var p in People)
Console.WriteLine(p.FullName);
}
}
again almost an identical procedure, other then when defining you're XmlSerializer you have to specify the type.
now the result of our efforts is
pretty neat, but i don't want the FirstName and LastName properties to be nodes of my person element, i want them to be attributes, and actually i don't want to even store the Id numbers of my employees.
well all i had to do is mark my properties with [XmlAttribute] attributes or [XmlIgnore] to modify my xml to what i had in mind
Pretty straight forward, there's numerous XmlAttributes to leverage
Now as the binaryformater had the ISerializable interface to intercept the serialization process the xmlSeraializer has the IXmlSerialisable interface. now this can be used to encrypt your data, but it could also be leveraged for just about any other manipulation you'd want of your data.
now the result of our efforts is
<?xml version="1.0"?>
<ArrayOfPerson xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Person>
<FirstName>John</FirstName>
<LastName>Smith</LastName>
</Person>
<Person>
<FirstName>Jane</FirstName>
<LastName>Doe</LastName>
</Person>
<Person xsi:type="Employee">
<FirstName>Sally</FirstName>
<LastName>Johnson</LastName>
<Id>0</Id>
</Person>
<Person>
<FirstName>Alejandro</FirstName>
<LastName>Cruz</LastName>
</Person>
<Person>
<FirstName>Diago</FirstName>
<LastName>Pendaz</LastName>
</Person>
<Person xsi:type="Employee">
<FirstName>Tim</FirstName>
<LastName>Chan</LastName>
<Id>1</Id>
</Person>
</ArrayOfPerson>
//for xml
serializtion class must be public
//base
classes need to have teh XmlInclude attribute
//with
any superclass types that inherit from them
[XmlInclude(typeof(Employee))]
[Serializable]
public class Person
{
//for xml
serialization all properties must have public setters
[XmlAttribute]
public string
FirstName { get; set; }
[XmlAttribute]
public string LastName
{ get; set; }
public Person() { }
public Person(string
FirstName, string LastName)
{
this.FirstName = FirstName;
this.LastName = LastName;
}
public string FullName
{ get { return $"{FirstName} {LastName}"; } }
}
[Serializable]
public class Employee : Person
{
static int
_runningId;
[XmlIgnore]
public int Id { get; set; } = _runningId++;
public string Wage { get; set; } = null;
public Employee() { }
public Employee(string
FirstName, string LastName) : base(FirstName, LastName) { }
}
<?xml version="1.0"?>
<ArrayOfPerson xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Person FirstName="John" LastName="Smith" />
<Person FirstName="Jane" LastName="Doe" />
<Person xsi:type="Employee" FirstName="Sally" LastName="Johnson" />
<Person FirstName="Alejandro" LastName="Cruz" />
<Person FirstName="Diago" LastName="Pendaz" />
<Person xsi:type="Employee" FirstName="Tim" LastName="Chan" />
</ArrayOfPerson>
Now as the binaryformater had the ISerializable interface to intercept the serialization process the xmlSeraializer has the IXmlSerialisable interface. now this can be used to encrypt your data, but it could also be leveraged for just about any other manipulation you'd want of your data.