Recently I needed to specify exactly how I would like a specific class serialized. Suppose we have the following simple schema:
<xs:schema targetNamespace="http://my.favourite.ns/person.xsd" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://my.favourite.ns/person.xsd"> <xs:complexType name="Person"> <xs:sequence> <xs:element name="Name" type="xs:string" /> <xs:element name="Surname" type="xs:string" /> <xs:element name="Age" type="xs:int" minOccurs="0" /> </xs:sequence> </xs:complexType></xs:schema>
Let's call this schema President.xsd.
A valid XML instance against this schema would be, for example:
<Person xmlns="http://my.favourite.ns/person.xsd"> <Name>Barrack</Name> <Surname>Obama</Surname> <Age>47</Age></Person>
Since we are serializing against a specific XML schema (XSD), we have an option of schema compilation:
xsd /c President.xsd
This, obviously, yields a programmatic type system result in a form of a C# class. All well and done.
Now.
If we serialize the filled up class instance back to XML, we get a valid XML instance. It's valid against President.xsd.
There is a case where your schema changes ever so slightly - read, the namespaces change, and you don't want to recompile the entire solution to support this, but you still want to use XML serialization. Who doesn't - what do you do?
Suppose we want to get the following back, when serializing:
<PresidentPerson xmlns="http://schemas.gama-system.com/ president.xsd"> <Name>Barrack</Name> <Surname>Obama</Surname> <Age>47</Age></PresidentPerson>
There is an option to override the default serialization technique of XmlSerializer. Enter the world of XmlAttributes and XmlAttributeOverrides:
private XmlSerializer GetOverridedSerializer(){ // set overrides for person element XmlAttributes attrsPerson = new XmlAttributes(); XmlRootAttribute rootPerson = new XmlRootAttribute("PresidentPerson"); rootPerson.Namespace = "http://schemas.gama-system.com/ president.xsd"; attrsPerson.XmlRoot = rootPerson;
// create overrider XmlAttributeOverrides xOver = new XmlAttributeOverrides(); xOver.Add(typeof(Person), attrsPerson);
XmlSerializer xSer = new XmlSerializer(typeof(Person), xOver); return xSer;}
Now serialize normally:
Stream ms = new MemoryStream();XmlTextWriter tw = new XmlTextWriter(ms, null);xSer.Serialize(tw, person);
This will work even if you only have a compiled version of your object graph, and you don't have any sources. System.Xml.Serialization.XmlAttributeOverrides class allows you to adorn any XML serializable class with your own XML syntax - element names, attribute names, namespaces and types.
Remember - you can override them all and still serialize your angle brackets.
Remember Me
The opinions expressed herein are my own personal opinions and do not represent my company's view in any way.
My views often change.
This blog is just a collection of bytes.
Copyright © 2003-2024Matevž Gačnik
E-mail