.NET Serialization, Part 2
by Wei-Meng Lee11/03/2003
In my last article, I discussed how to serialize objects into a binary stream, as well as into a SOAP message. A third way to serialize an object is to serialize it into an XML document. There are many advantages to XML serialization -- XML documents are platform-agnostic, since they is in plain text format and that makes cross platform communications very easy. XML documents are also easy to read and modify, which makes XML a very flexible format for data representation.
In this article, I will illustrate XML serialization with an example and show you some of its uses.
Defining Our Sample Class
Let's define a class so that we can see how XML serialization works. For this example, I have defined a Member class that allows you to store information about a person, such as name, addresses, and date of birth. Here is the class definition:
Public Class Member
Private age As Integer
Public Name As CName
Public Addresses() As CAddress
Public DOB As Date
ReadOnly Property currentAge()
Get
age = DateDiff(DateInterval.Year, DOB, Now)
Return age
End Get
End Property
End Class
Public Class CName
Private pFirstName, pLastName As String
Property FirstName()
Get
Return pFirstName
End Get
Set(ByVal Value)
pFirstName = Value
End Set
End Property
Property LastName()
Get
Return pLastName
End Get
Set(ByVal Value)
pLastName = Value
End Set
End Property
End Class
Public Class CAddress
Public Line1 As String
Public Line2 As String
Public City As String
Public Country As String
Public Postal As String
End Class
I have deliberately designed my class so that I can illustrate the various aspects of XML serialization. Here are the specifics:
- The
Memberclass contains both private and public variables. It also contains aREADONLYproperty. - The
Memberclass contains a public array containing the addresses of aMember. - The
Memberclass contains a variable ofDatedata type. - The
CNameclass contains two private variables and two properties. - The
CAddresscontains only public variables.
To serialize a Member object into a XML document, I used the XMLSerializer class from the System.Xml.Serialization namespace:
Imports System.Xml.Serialization
'========XML Serialization=========
Sub XMLSerialize(ByVal mem As Member)
Dim wri As New StreamWriter("c:\Members.xml")
Try
Dim ser As New XmlSerializer(GetType(Member))
ser.Serialize(wri, mem)
Catch ex As Exception
MsgBox(ex.ToString)
Finally
wri.Close()
End Try
End Sub
Assuming I have the following object declaration:
Dim mem As New Member
Dim memName As New CName
memName.FirstName = "Wei-Meng"
memName.LastName = "Lee"
mem.Name = memName
mem.DOB = "5/1/1972"
Dim address As New CAddress
address.Line1 = "One Way Street"
address.Line2 = "Infinite Loop"
address.Country = "SINGAPORE"
address.Postal = "456123"
Dim addresses(1) As CAddress
addresses(0) = address
addresses(1) = address
mem.Addresses = addresses
To serialize the Member object, invoke the XMLSerialize() method, as shown earlier:
XMLSerialize(mem)
The XML document generated looks like this:
<?xml version="1.0" encoding="utf-8"?>
<Member xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Name>
<FirstName xsi:type="xsd:string">Wei-Meng</FirstName>
<LastName xsi:type="xsd:string">Lee</LastName>
</Name>
<Addresses>
<CAddress>
<Line1>One Way Street</Line1>
<Line2>Infinite Loop</Line2>
<Country>SINGAPORE</Country>
<Postal>456123</Postal>
</CAddress>
<CAddress>
<Line1>One Way Street</Line1>
<Line2>Infinite Loop</Line2>
<Country>SINGAPORE</Country>
<Postal>456123</Postal>
</CAddress>
</Addresses>
<DOB>1972-05-01T00:00:00.0000000-07:00</DOB>
</Member>
As you can see, the object is serialized into an XML document with a format corresponding to the structure of the object. (To de-serialize the XML document, simply use the Deserialize() method from the XMLSerializer class.)
Here are some important points to note:
- The
Cityinformation is not persisted in the XML document, as it is not assigned in the object. I will show you later how to ensure that an empty element is inserted, even though a value is not assigned. - All
READ/WRITEproperties in the object are persisted in the XML document, except theREADONLY currentAgeproperty in theMemberclass. - Only public variables are persisted; private variables are not persisted in XML serialization.
- The default name for each element in the XML document takes after the variable (or class) name. In most cases this is desirable, except in the case where the individual address is represented by the
<caddress>element (which may not be too obvious to the person reading the XML document).
Despite the fairly automated task performed by the XMLSerializer object, you can customize the way the XML document is generated. Let's modify our classes with a few attributes. Here is the modified class:
<XmlRoot("MemberInformation", _
Namespace:="http://www.mycompany.com", _
IsNullable:=True)> _
Public Class Member
Private age As Integer
' specify the element name to be MemberName
<XmlElement("MemberName")> _
Public Name As CName
' specify the sub-element(s) of Addresses to be Address
<XmlArrayItem("Address")> _
Public Addresses() As CAddress
Public DOB As Date
ReadOnly Property currentAge()
Get
age = DateDiff(DateInterval.Year, DOB, Now)
Return age
End Get
End Property
End Class
Public Class CName
Private pFirstName, pLastName As String
Property FirstName()
Get
Return pFirstName
End Get
Set(ByVal Value)
pFirstName = Value
End Set
End Property
Property LastName()
Get
Return pLastName
End Get
Set(ByVal Value)
pLastName = Value
End Set
End Property
End Class
Public Class CAddress
Public Line1 As String
Public Line2 As String
' empty element if city is not specified
<XmlElement(isnullable:=True)> _
Public City As String
' specify country and postal as attribute
<XmlAttributeAttribute()> _
Public Country As String
<XmlAttributeAttribute()> _
Public Postal As String
End Class
When the class is serialized, the XML document looks like this:
<?xml version="1.0" encoding="utf-8"?>
<MemberInformation xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.mycompany.com">
<MemberName>
<FirstName xsi:type="xsd:string">Wei-Meng</FirstName>
<LastName xsi:type="xsd:string">Lee</LastName>
</MemberName>
<Addresses>
<Address Country="SINGAPORE" Postal="456123">
<Line1>One Way Street</Line1>
<Line2>Infinite Loop</Line2>
<City xsi:nil="true" />
</Address>
<Address Country="SINGAPORE" Postal="456123">
<Line1>One Way Street</Line1>
<Line2>Infinite Loop</Line2>
<City xsi:nil="true" />
</Address>
</Addresses>
<DOB>1972-05-01T00:00:00.0000000-07:00</DOB>
</MemberInformation>
Here are the uses of each attribute:
<XmlRoot("MemberInformation", _
Namespace:="http://www.mycompany.com", _
IsNullable:=True)> _
Public Class Member
...
Sets the root element name of the XML document to be MemberInformation (default element name is Member, which follows the class name), with a specific namespace. The IsNullable attribute indicates if empty elements must be displayed.
<XmlElement("MemberName")> _
Public Name As CName
...
Specifies that the element name MemberName be used in place of the current variable name (as defined in the class as CName).
<XmlArrayItem("Address")> _
Public Addresses() As CAddress
...
Specifies that the following variable is repeating (an array) and that each repeating element be named as Address.
<XmlElement(isnullable:=True)> _
Public City As String
...
Indicates that the document must include the City element even if it is empty.
<XmlAttributeAttribute()> _
Public Country As String
Indicates that the Country information be represented as an attribute.
XML Serialization Needs a Default Constructor
There is one more thing that you need to take note of when doing XML serialization. If your class has a constructor (as the following example shows), then you would also need a default constructor:
Public Class Points
Sub New(ByVal x As Single, ByVal y As Single)
End Sub
Property x()
Get
End Get
Set(ByVal Value)
End Set
End Property
Property y()
Get
End Get
Set(ByVal Value)
End Set
End Property
End Class
The above example will result in an error when you try to perform XML serialization on it. To solve the problem, simply add a default constructor to your class definition:
Public Class Points
Sub New()
End Sub
Sub New(ByVal x As Single, ByVal y As Single)
End Sub
Property x()
Get
End Get
Set(ByVal Value)
End Set
End Property
Property y()
Get
End Get
Set(ByVal Value)
End Set
End Property
End Class
Uses of XML Serialization
Now that we have seen how XML serialization works, what are its uses? For one, it can help you to preserve the state of your object (just like the binary and SOAP serialization that you saw in my last article) and makes transportation easy. More significantly, I often use XML serialization to manage configuration files. I can define a class to store configuration information and use XML serialization to persist it on file. By doing so, I have the flexibility to modify the configuration information easily, since the information is now represented in XML; at the same time, I can programmatically manipulate the configuration information by accessing the object's properties and methods.
Wei-Meng Lee (Microsoft MVP) http://weimenglee.blogspot.com is a technologist and founder of Developer Learning Solutions http://www.developerlearningsolutions.com, a technology company specializing in hands-on training on the latest Microsoft technologies.
Return to ONDotnet.com
-
response from webservice using class file
2007-08-29 04:16:29 Razzaq [View]
-
serialization in Webservices
2006-01-26 08:36:52 FUCK [View]
-
Even greater control over serialization
2004-08-05 22:33:05 kzu [View]
-
Uses of XML Serialization
2003-12-09 11:03:05 anonymous2 [View]
-
Uses of XML Serialization
2004-03-27 22:34:12 t_s [View]
-
Uses of XML Serialization
2004-01-03 16:22:58 anonymous2 [View]
-
Uses of XML Serialization
2003-12-09 11:02:37 anonymous2 [View]
-
Uses of XML Serialization
2004-01-03 16:15:33 anonymous2 [View]


