XML Serialization


XML serialization differs from binary serialization in two ways. First, the types of data that can be serialized are limited. Second, type information is not serialized with the data, which means that there s no guarantee that the serialized object will be deserialized to the same object type. The following list describes the item types that can be serialized using XML serialization:

  • Public fields and read/write properties of public classes (read-only properties will not be serialized)

  • Classes implementing ICollection and IEnumerable

  • XmlElement objects

  • XmlNode objects

  • DataSet objects

  • Classes with default constructors

Before getting into too much detail, let s take a quick look at a simple XML serialization sample. The following code fragment is the class definition to be serialized:

C#

 publicclassMyXmlSimpleData { publicintIntField; publicstringStringField; publicDateTimeCurrentDate; privateintPrivateField; publicMyXmlSimpleData() { IntField=1234; StringField= "XmlSimpleSerialization"; CurrentDate=DateTime.Today; PrivateField=333; } } 

Visual Basic .NET

 PublicClassMyXmlSimpleData PublicIntFieldasInteger PublicStringFieldasString PublicCurrentDateasDateTime PrivatePrivateFieldasInteger PublicSubNew() IntField=1234 StringField= XmlSimpleSerialization" CurrentDate=DateTime.Today PrivateField=333 EndSub EndClass 

First notice that no special attribute tags are required to indicate that this class can be serialized, as is the case with binary serialization. The process of serializing the class is extremely simple, as the following code illustrates:

C#

 MyXmlSimpleDataxmlData; XmlSerializerxmlDataSerializer; StreamWriterstreamFileWriter; xmlData=newMyXmlSimpleData(); xmlDataSerializer=newXmlSerializer(typeof(MyXmlSimpleData)); streamFileWriter=newStreamWriter(simple.xml); xmlDataSerializer.Serialize(streamFileWriter,xmlData); 

Visual Basic .NET

 DimxmlDataasMyXmlSimpleData DimxmlDataSerializerasXmlSerializer DimstreamFileWriterasStreamWriter xmlData=newMyXmlSimpleData() xmlDataSerializer=newXmlSerializer(GetType(MyXmlSimpleData)) streamFileWriter=newStreamWriter(simple.xml) xmlDataSerializer.Serialize(streamFileWriter,xmlData) 

In this example, an instance of the MyXmlSimpleData class is instantiated first and then XmlSerializer is created, which requires the data type of the class to be serialized ”in this case, MyXmlSimpleData . In the next step, the stream is created, which is a simple file. Finally, the object is serialized to the stream. Once the object is serialized to the stream, the following code will deserialize it:

C#

 MyXmlSimpleDataxmlData; XmlSerializerxmlDataSerializer; FileStreamxmlFileStream; xmlDataSerializer=newXmlSerializer(typeof(MyXmlSimpleData)); xmlFileStream=newFileStream(simple.xml",FileMode.Open); xmlData=(MyXmlSimpleData)xmlDataSerializer.Deserialize(xmlFileStream); 

Visual Basic .NET

 DimxmlDataasMyXmlSimpleData DimxmlDataSerializerasXmlSerializer DimxmlFileStreamasFileStream xmlDataSerializer=newXmlSerializer(GetType(MyXmlSimpleData)) xmlFileStream=newFileStream(simple.xml",FileMode.Open) xmlData=xmlDataSerializer.Deserialize(xmlFileStream) 

The steps are very similar to the serialization process shown earlier. The difference is that we don t instantiate an instance of MyXmlSimpleData because we re retrieving it from the stream, and the Deserialize method is called instead with the data stream.

After serializing the object to the stream, which in this case is a file, you can take a look at the resulting XML. The following code is the XML generated for the preceding class. Notice that only the public properties are included ” that is, there s no PrivateField entry. Also notice that there s no type information ”just the values for each field.

 <?xmlversion="1.0 encoding="utf-8 ?> <MyXmlSimpleDataxmlns:xsd="http://www.w3.org/2001/XMLSchema  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <IntField>1234</IntField> <StringField>XmlSerializationSample</StringField> <CurrentDate>2003-02-09T00:00:00.0000000-08:00</CurrentDate> </MyXmlSimpleData> 

Controlling XML Serialization

As is the case with binary serialization, XML serialization involves attributes that control how a class is serialized using the XmlSerializer formatter. One such attribute is the XmlElement attribute. Each attribute contains any number of constructors as well as properties that can be assigned in the attribute applied to a class or a class member. For example, in the following code snippet, the XmlElement attribute is used to rename the IntField1 property from the default value of IntField1 to Integer_Field :

C#

 publicclassMyRenamedXmlData { [XmlElement(ElementName= Integer_Field)] publicintIntField1; } 

Visual Basic .NET

 PublicClassMyRenamedXmlData <XmlElement(Integer_Field)>_ PublicIntField1asInteger EndClass 

As mentioned, the XmlElement attribute is just one of many attributes that can be applied to a class definition that affects the generated XML. Table 4-2 lists the different attributes that can be applied to classes and class members . Notice that when specifying an attribute within a class definition, the last Attribute text is left off. For example, in the preceding code snippet, we specified XmlElement instead of XmlElementAttribute . Also, within the parentheses following each XML attribute, any public properties exposed by that attribute class can be set. In this example, ElementName is a property of the XmlElementAttribute class. The Visual Basic .NET syntax is slightly different. First, instead of square brackets, angled brackets denote the attribute, and second, the property is passed to the constructor for the XmlElementAttribute class.

Table 4-2: XML Attributes

Attribute

Description

XmlAnyAttributeAttribute

Indicates that all XML attributes unknown to the schema should be placed in an array of XmlAttribute objects on deserialization

XmlAnyElementAtribute

Indicates that all XML elements unknown to the schema should be placed in an array of XmlElement objects on deserialization

XmlArrayAttribute

Controls properties of an array

XmlArrayItemAttribute

Controls individual elements within an array

XmlAttributeAttribute

Indicates that the class should be serialized as an XML attribute

XmlChoiceIdentifierAttribute

Indicates that the member can be described by an enumerated list

XmlElementAttribute

Indicates that the member will be serialized as an XML element

XmlEnumAttribute

Controls the element name of an enumeration member

XmlIgnoreAttribute

Indicates that the member should be ignored when serialized

XmlIncludeAttribute

Indicates that the class should be included when generating schemas

XmlNamespaceDeclarationsAttribute

Indicates that a property, parameter, return value, or class member contains a prefix associated with namespaces used within the XML document

XmlRootAttribute

Indicates a class, a structure, an enumeration, or an interface as the root element of the XML document

XmlTextAttribute

Indicates that the member should be serialized as XML text

XmlTypeAttribute

Controls the name and namespace of the XML type

Although we won t get into the specifics of every attribute that can possibly be applied to a class, the xmlserial.cs sample illustrates several XML attributes. You can find this program in the companion content in the folder Chap04\xml\cs. Again, a Visual Basic .NET version of the same program is available under the vb.net folder. For a full description of each attribute and its properties, consult the Platform SDK or the .NET Framework SDK.

Overriding XML Serialization

As we saw in the previous section, the XML generated in the serialization process can be modified by applying attributes. However, what if you have a situation in which you need to generate multiple XML streams? Let s say, for instance, that in the MyRenamedXmlData class, the property name for IntField1 needed to be different depending on the consumer of the serialized XML. In this case, applying an attribute would not suffice because the applied attribute is always used when using the default XML serializer. You need to override the default XML serialization.

The process of overriding the default XML serialization requires the following steps:

  1. Create one or more XML attributes (such as those listed in Table 4-2) that apply to one element within the class to serialize. Remember that these attributes are actually classes with properties and methods .

  2. Create an instance of the XmlAttributes class that each XML attribute created in step 1 is added to.

  3. Create an instance of the XmlAttributeOverrides class that applies the XmlAttributes class to a specified class property or method.

The following code illustrates overriding the default XML serialization process by implementing the custom serialization in the OverrideSerialization method:

C#

 publicclassMyXmlOverrideSample { publicintIntField1; publicDateTimeCurrentDate; publicvoidOverrideSerialization(FileStreamfileStream) { XmlElementAttributexmlElementAttribute=newXmlElementAttribute(); XmlAttributesxmlAttributes=newXmlAttributes(); XmlAttributeOverridesxmlAttributeOverrides=new XmlAttributeOverrides(); XmlSerializerxmlSerializer=null; xmlElementAttribute.ElementName=  "Override_Integer_Field_Numero_Uno"; xmlAttributes.XmlElements.Add(xmlElementAttribute); xmlAttributeOverrides.Add(typeof(MyXmlOverrideSample),  "IntField1",xmlAttributes); xmlSerializer=newXmlSerializer(typeof(MyXmlOverrideSample), xmlAttributesOverride); xmlSerializer.Serialize(filesStream,this); } } 

Visual Basic .NET

 PublicClassMyXmlOverrideSample PublicIntField1asInteger PublicCurrentDateasDateTime PublicSubOverrideSerialization(fileDataStreamasFilestream) DimxmlElementAttrasXmlElementAttribute=newXmlElementAttribute() DimxmlAttrasXmlAttributes=newXmlAttributes() DimxmlOverridesasXmlAttributeOverrides=new_ XmlAttributeOverrides() DimxmlDataSerializerasXmlSerializer xmlElementAttr.ElementName= Override_Integer_Field_Numbero_Uno" xmlAttr.XmlElements.Add(xmlElementAttr) xmlOverrides.Add(GetType(MyXmlOverrideSample), IntField1",_ xmlAttr) xmlDataSerializer=newXmlSerializer(GetType(MyXmlOverrideSample),_ xmlOverrides) xmlDataSerializer.Serializer(fileDataStream,this) EndSub EndClass 

This example shows a method that serializes the class to a stream but changes the XML element name for the IntField1 member to Override_Integer_Field_Numero_Uno . Note that when the object is serialized, the remaining properties that were not overridden are serialized as expected.

As we mentioned, the xmlserial.cs and xmlserial.vb samples provide code that performs XML serialization on a variety of classes: a simple class, one with XML attributes applied, and one that overrides serialization. See the sample for the complete code listing.




Network Programming for the Microsoft. NET Framework
Network Programming for the MicrosoftВ® .NET Framework (Pro-Developer)
ISBN: 073561959X
EAN: 2147483647
Year: 2003
Pages: 121

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net