The new vbAccelerator Site - more VB and .NET Code and Controls
Source Code
5 Internet &nbsp

XML PropertyBag

Persist and Restore your data in a manageable, reusable and extensible way with XML



NOTE: this code has been superceded by the version at the new site.




Using MS XML Parser Technology


Download Code
Download the VB5 XML Property Bag DLL and Demonstration Project (30kb)
Download the VB6 XML Property Bag DLL and Demonstration Project (30kb)

&nbsp Before you Begin &nbsp
&nbsp These projects require Internet Explorer 5 or higher to be installed because they use the Microsoft XML Parser (msxml.dll). This DLL is also available as a redistributable for users of Internet Explorer 4.0. Visit the Microsoft XML site for (confusing) information about this. &nbsp

&nbsp
Overview
This ActiveX DLL is derived from an excellent original XML PropertyBag sample by Aaron Anderson (Aaron.Anderson@mail.farmcreditbank.com). It allows you to persist and recreate your own objects directly to XML based-files using a simple interface closely related to VB's PropertyBag object. By implementing one interface in your class you will gain the ablility to save state and restore again for any number of objects to and from a single XML file. Full support for binary data means you can store blobs in your XML file too.

About XML
The advantages of using XML as a file format for storage in your application cannot be understated. XML is plain text. You can read and write XML files by hand (although you might find that a little tedious!) XML is also self-describing. Just looking at an XML file gives you a good idea what it does and its generally easy to tell how to read the file. On top of that, XML parsers offer three unique features not often seen before the success of the HTTP protocol: they're almost always free, they have a standardised API and they're available for almost any useful computer you can think of (except Windows CE. Hmmm. Maybe that's not actually a useful computer anyway).

Anyway, I'm sure you don't need me to tell you that XML is a good idea. Visit Microsoft's XML site for some more ideas and examples!
The XMLPropertyBag
The XMLPropertyBag object provided with this article comes in two parts: a implementable interface IXMLPropertyBag and a creatable class XMLPropertyBag. To take advantage of the XML Property Bag features, your class should implement the IXMLPropertyBag interface. Doing this effectively adds ReadProperties and WriteProperties events to your object, passing an XMLPropertyBag in as a parameter. The only difference between these events and ones in VB's PropertyBag implementations is that they are prefixed with IXMLPropertyBag_ rather than the base object type name (e.g. UserControl_ ).

Once you have implemented this interface, to provide XML saving and restoring of values can be done in two steps: firstly you write the code in the ReadProperties and WriteProperties methods, and then you write code in the object's owner to initialise reading and writing of values.

Reading and Writing properties is done in almost exactly the same way as with VB's PropertyBag object. The ReadProperty method of the XMLPropertyBag allows you to read the value of a named variant in the property bag and the WriteProperty method does the opposite. The following types of variant can be read and written:
  • Date. Dates are stored as strings, so you may wish to convert to a fixed string representation if your XML file will be used across locales. For example, mm/dd/yyyy and dd/mm/yyyy are the US and UK representations of the same date and cannot be interchanged.
  • Number. Numbers are stored as strings, so be careful with numbers containing decimal points if you expect your XML file to travel between locales. For example, the number 10,6 is valid on a machine with French locale settings but not on a UK machine.
  • String - note you can also store strings using byte arrays instead if you want to be sure to save String data in a completely platform independent way. The XMLPropertyBag will automatically mark up String sections as XML CDATA if it sees any XML tokens in the string.
  • Byte Array. Byte arrays are stored as Base64 encoded data so are guaranteed to be transferred unchanged across any system. The disadvantage to this is that Base64 encoding requires 4 bytes in the XML file for every 3 bytes passed in, rounded up to the nearest 4 bytes.
  • An object which Implements IXMLPropertyBag. To do this, you pass in the object as the DefaultValue member of the ReadProperties method. There is no default ability for these objects.
The XMLPropertyBag code will attempt to read/write all other types as a string, but if there is no suitable format available you will get an Invalid Variant Type error.

Having implemented these methods, you can then save and restore objects into XML. In the object's owner, create a new instance of the XMLPropertyBag object. If you are saving the object's state, then call the SaveState method on the object, passing in the object to save as the first parameter. You can call SaveState on as many objects as you wish - they will be added to the same XML Document. The optional sName parameter allows you to distinguish between multiple objects of the same type in the same XML file. When complete, you can then get the XML rendering of the objects from the Contents property, which you can then save to whatever storage you are persisting the content to.

To restore objects from the XML, set the Contents property to the saved XML. Then you can call RestoreState, passing in each object you wish to restore (and optionally the name if you used that).
Quick Start
This discussion demonstrates how you can add persistance to a simple class called in your application. First, assume the class is called cName and has the following definition:

Option Explicit

Private m_sFirstName As String
Private m_sLastName As String

Public Property Get FirstName() As String
FirstName = m_sFirstName
End Property
Public Property Let FirstName(ByVal sName As String)
m_sFirstName = sName
End Property

Public Property Get LastName() As String
FirstName = m_sFirstName
End Property
Public Property Let LastName(ByVal sName As String)
m_sLastName = sName
End Property

The first step is to implement the IXMLPropertyBag interface. Add this code to the class:

Implements IXMLPropertyBag

...

Private Sub IXMLPropertyBag_ReadProperties(ByVal PropertyBag As vbalXMLPBag.XMLPropertyBag)
'
End Sub

Private Sub IXMLPropertyBag_WriteProperties(ByVal PropertyBag As vbalXMLPBag.XMLPropertyBag)
'
End Sub

Now you can fill in your ReadProperties and WriteProperties implementations:

Private Sub IXMLPropertyBag_ReadProperties(ByVal PropertyBag As vbalXMLPBag.XMLPropertyBag)
'
FirstName = PropertyBag.ReadProperty("FirstName", "")
LastName = PropertyBag.ReadProperty("LastName", "")

End Sub

Private Sub IXMLPropertyBag_WriteProperties(ByVal PropertyBag As vbalXMLPBag.XMLPropertyBag)
'
PropertyBag.WriteProperty "FirstName", FirstName, ""
PropertyBag.WriteProperty "LastName", LastName, ""

End Sub
Once that is done, you can now save and restore cName objects at will. For example, this code:

Private m_cN As New cName

Public Function SaveName() As String

' Create an instance of the XML Property bag object:
Dim oP As New XMLPropertyBag

' Save cName into the property bag:
oP.SaveState m_cN

' Now the content is saved in the return value:
SaveName = oP.Contents

End Sub

Public Sub RestoreName(ByVal sXML As String)

' Create an instance of the XML Property bag object:
Dim oP As New XMLPropertyBag

' Load the XML into it:
oP.Contents = sXML

' Restore the object:
oP.RestoreState m_cN

End Sub

The download code includes a sample demonstrating how to store a Person object which in turn holds a collection of Address objects. Another example is available in the Search and Replace utility.



TopBack to top
Source Code - What We're About!Back to Source Code

&nbsp

AboutContributeSend FeedbackPrivacy

Copyright 2000, Steve McMahon ( steve@vbaccelerator.com). All Rights Reserved.
Last updated: 21 March 2000