BizTalk Utilities CV ,   Jobs ,   Code library  
 
Home Page
XmlSerializer
Advanced XmlSerializer
XmlSerializer Attributes
Runtime exceptions
Serializing Collection Classes
Serializing Arrays
XmlElement Attribute Type
XmlIncludeAttribute
XmlSerializer
Serialization Attributes
Serializable Classes
Deserializing an object
Serializing an object
Serialize Class
Metadata Attributes
<< XML DOM
XQuery >>

By :Mark Wilson
I am the creator of TopXML. I am available for international and local (Australia) contracts. I am a Solution Architect/Business Analyst. I have worked in IT in several countries (NZ, Australia, South Africa, UK) building and training teams for government and very large non-governmental organizations. I am ex-Microsoft Consulting Services. I wrote the first book on Microsoft XML published in 2000 called XML Programming with VB and ASP. Most recently I have been building tools for the SEO industry. Ask me for a 37 point SEO health-checkup for your website.
First posted :03/24/2008
Times viewed :1945

 

Customizing Xml Serialization

Previously we covered developing classes containing metadata attributes that the XmlSerializer maps to an XML type. This is great when we develop classes ourselves, but we can not apply this technique when we are in not in control of the source code. But does that mean we are out of luck when we need to customize how classes from third-party libraries map to XML or when the mappings defined by a class need modification?

No, it does not. Fortunately there are alternatives to attaching attributes in code. There are several overloads for the constructor of the XmlSerializer to customize type mappings at runtime. Table 10.1 shows the available overloads. These constructors can customize type mappings and declare additional types to the XmlSerializer.

1.3            Table 10.1: All available overloads for the constructor of the XmlSerializer class. Each overload allows customizing the serialization at run-time

Constructor Signature

Description

XmlSerializer(Type type);

Create an XmlSerializer for type

XmlSerializer(XmlTypeMapping mapping);

Provide a custom type mapping to use for serialization

XmlSerializer(Type type,

  string defaultNamespace);

Create an XmlSerializer for type and specify the default namespace for all serialized objects

XmlSerializer(Type type, Type[] extraTypes);

Create an XmlSerializer for type and the types in the extraType array

XmlSerializer(Type types,

  XmlAttributeOverrides overrides);

Create an XmlSerializer for type and apply customization the attributes in overrides

XmlSerializer(Type type,
  XmlRootAttribute root);

Create an XmlSerializer for type and change the root element to root

XmlSerializer(Type type,

  XmlAttributeOverrides overrides,
  Type[] extraTypes,
  XmlRootAttribute root,
  string defaultNamespace);

Create an XmlSerializer for type and the types in the extraType array, apply customization the attributes in overrides, change the root element to root and specify the default namespace for all serialized objects

Declaring Types at Runtime

Previously we learned that the XmlSerializer has to analyze the types it is going to process before it is ready to convert XML to objects and vice-versa. We also learned several techniques based on metadata attributes to explicitly declare derived types, which the serializer can not automatically discover during the analysis. During the class analysis, the serializer checks for the attributes and records the type substitutions they declare. Obviously theses techniques only work to declare substitutions with types that exist at the time we write the declarations. We need a different solution for substitutions we can not declare in code. Take a collection class, like the ArrayList. There is no way Microsoft could declare all the types people are going to store inside an ArrayList. In fact they did not attach attributes inside the ArrayList class. Hence, serializing an ArrayList referencing anything else than objects of type object like in the following example causes an exception.

public static void BlowUpTheSerializer()

{

  ArrayList list = new ArrayList();

  list.Add( "aString" );

  XmlTextWriter writer = new

    XmlTextWriter( "List.xml", System.Text.Encoding.UTF8 );

  XmlSerializer serializer = new
      XmlSerializer(typeof(ArrayList));

  serializer.Serialize( writer, list ); // BOOM!

}

Adding Global Type Declarations

Serialize() throws the exception because the XmlSerializer’s initial type analysis for the ArrayList found that all elements inside the ArrayList are declared to be of type object because the ArrayList needs to be able to reference ANY type. If we want to serialize an ArrayList referencing anything other than objects we need to declare the types differently.

The XmlSerializer allows declaring type global globally, by passing a Type array with the global types to the constructor. The following line, for example, would declare the string type within the ArrayList to avoid the exception in the example above:

  XmlSerializer serializer = new 
      XmlSerializer(typeof(ArrayList),  // primary type declaration

        new Type[] {typeof(string)} );  // global type declaration.

With the global type declaration in place, the ArrayList in the example above serializes to the following XML document.

<?xml version="1.0" encoding="utf-8" ?>

<ArrayOfAnyType

  xmlns:xsd="http://www.w3.org/2001/XMLSchema"

  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <anyType xsi:type="xsd:string">aString</anyType>

</ArrayOfAnyType>

The root element’s name follows the XmlSerializer’s naming scheme for all arrays and collections: It appends the type of the items within the array to “ArrayOf”. The array item’s node name identifies the declared item type (“anyType” is the XSD equivalent of the Object class, i.e. the root class of all classes). To identify the type of the actual object, the XmlSerializer added an xsi:type="xsd:string" attribute to the element.

Type Resolution With Global Type Declarations

For every field of an object the XmlSerializer serializes, it first checks the referenced object’s type against the declared type of the field. If the object’s type does not match the declared type, it checks against types declared by an XmlIncludeAttribute attached to the declared type. Finally, if the object’s type does not match any included type, it checks the global type declarations. If the serializer finds a match it proceeds to serialize the type. Otherwise it will throw an exception.

When the XmlSerializer deserializes an XML type it checks whether an element matches the corresponding field name. If the name matches, it checks the element for an xsi:type attribute and compares the attribute’s values against the global type declarations. When it finds a match it deserializes the object in the stream based on the type mapping for the matching type.


Rate this article on a scale of 1 to 10

Your vote :  


 

Recent Jobs

A great opportunity to Digital Vide
here is a greate opportunity as a S
A great opportunity as a Network En
A Greate Opportunituy as a SQL Deve
An immediate job opportunity as a B

View all Jobs (Add yours)
View all CV (Add yours)



chicago web site design
free conference call
Host Department NOLIMIT Web Hosting
UK Web Design
Donna karan sunglasses
New Jersey pool contractor
answering service
masks
swimming pool builder
MSN
sunglasses


    Email TopXML  

Front Page Daily Stuff TopXML Forum XML blogs XML Newsgroups BizTalk Biztalk Utilities Biztalk Utilities Tutorial B2B SAP XML Microsoft .NET Dotnet System XML Soapformatter SQLXML XMLserializer XQuery PHP PHP SimpleXML PHP XML Dom PHP XML RPC PHP XSLT Java Java Java XML Xalan Microsoft ASP ASP Schemas XML SQL Server XML XMLDom XSL XSL Tutorial XSLT Stylesheets General Javascript CSS XHTML WAP