Click here to Skip to main content
Licence 
First Posted 1 Dec 2002
Views 93,235
Bookmarked 32 times

XML Property Bag Implementation

By | 1 Dec 2002 | Article
This is an ATL/COM-port of Don Box' excellent XML property bag implementation.

Introduction

First I'll assume you know COM. It wouldn't hurt to understand the concepts of serialization, nor does it hurt to have used the interfaces IPropertyBag and IPersistPropertyBag.

This is a port of Don Box' excellent XML property bag implementation. It's a COM class which implements the IPropertyBag interface, meaning that it can serialize and deserialize COM objects implementing the IPersistPropertyBag interface.

Property bags are essentially a collection of name/value pairs. When an object is serialized, the property bag basically asks the object to give it all its properties along with their names. Conversely, when an object is deserialized, the property bag asks the object to repopulate its properties using what's available in the property bag.

This information exchange is done through the interfaces IPropertyBag and IPersistPropertyBag. The property bag implements IPropertyBag and the serialized/deserialized object implements IPersistPropertyBag.

A serialization call sequence might look like this:

IPropertyBag::SaveToFile("file", pUnkObject);   
     |
     v
IPersistPropertyBag* pPersist;
pUnkObject->QueryInterface(
    IID_IPersistPropertyBag,
    &pPersist);
pPersist->Save(this, ...) --> IPersistPropertyBag::Save(IPropertyBag* pPropBag, ...)
                                                   |
                                                   v
                                         foreach(p in properties) {
IPropertyBag::Write(BSTR name,  <----  pPropBag->Write(p.bstrName, &p.varValue);
                    VARIANT* value)      }
    |
    v
Make data persistant (e.g. save to file)                                  

Ok, first I apologize for not drawing a proper picture, but I don't own a decent drawing program. Second, I'd like to inform you that it's in IPropertyBag::Write where the magic happens. Typically, it's here where data is made persistent. In this implementation, it generates an XML element inside an XML document which is written to disk after all properties have been saved.

IPropertyBag::Write can do more magic than meets the eye. If the variant it's been passed contains an interface pointer, it will be queried for the IPersistPropertyBag interface. If the query yields an interface pointer, it will be used recursively. Thus it is possible to serialize trees of objects.

Deserialization works similarly to serialization. IPersistPropertyBag::Read() is called instead of IPersistPropertyBag::Write(). The object being deserialized calls IPropertyBag::Read() instead of IPropertyBag::Write(). Not really hard at all.

IXMLPropertyBag

The implemented interface, besides IPropertyBag, contains only two methods:

[
    object,
    uuid(FC34FA47-86F7-4B19-88FA-43E073F29E14),
    dual,
    nonextensible,
    helpstring("IXMLPropertyBag Interface"),
    pointer_default(unique)
]
interface IXMLPropertyBag : IDispatch {
    // Serializes an object to an XML file
    [id(1)] HRESULT SaveToFile([in] BSTR bstrFileName, [in] IUnknown* pObject);
    [id(2)] HRESULT LoadFromFile([in] BSTR bstrFileName, 
        [in] IErrorLog* pErrorLog, [out,retval] IUnknown** ppObject);
};

The function LoadFromFile takes not only a file name and returns an object, it also takes an interface pointer to an error log object. This log is used when the deserialization process encounters errors.

Handled VARIANTs

This implementation can handle any variant except these:

  • which are by reference - VT_BYREF
  • which are arrays - VT_ARRAY
  • which cannot be transformed into strings - BSTR

Please note that user data types, VT_RECORD, are supported provided that type library information exists for that type.

Why use my code instead of Don Box'?

  • My code is compile and go. You get a ready to use DLL, while Don Box' implementation is really just a CPP file showing "This is how it can be done".
  • I believe I use less resources. Don Box' allocated a new property bag for each property which implemented IPersistPropertyBag. I don't do that, I use a stack where I store the XML element nodes instead, so that I can "backtrack".

Caveat Emptor

This software is far from complete and perfect. Here's a list of issues you should be aware of:

  • Property names cannot contain anything that would syntactically interfere with XML

    Property names are now mangled so that they never interfere with the XML syntax.

  • Property values cannot contain anything that would syntactically interfere with XML

    Maybe I should get a clue. Special XML characters are in fact escaped in text.

  • Source code looks like crap in other editors than mine.

    The reason is that Mr. Box uses spaces for tabbing, while I use the real McCoy. I may get around to beautify the code at some point.

  • Error log is not used

    Mr. Box never implemented error logging. I will most likely do it too once I find some implementation of IErrorLog.

  • XML is verbose

    XML may inflate your data quite a lot, and there is little you can do about it. The benefits of storing data as XML though is that you can use other tools to manipulate it and you can edit it by hand using a text editor.

License Grant

You are granted a license to use the code for whatever purpose, if and only if the following conditions are met: You may expect no warranties from my part. If you break something, you fix it. If we meet some day in the flesh, you may buy me a beer of my choice. This is not a requirement, but it would be a very nice thing to do and I would appreciate it. If your religion prohibits you from buying any alcohol, even if not for yourself, a coke is fine or whatever well testing beverage which you find morally and ethically acceptable.

Also, remember that portions of this code is copyright Don Box.

By the way, many thanks goes to Mr. Don Box for this excellent piece of code.

Revision history

  • 2002-12-02

    Initial version.

  • 2002-12-03

    Typos, bloody typos.

  • 2002-12-03

    XML text is escaped automagically with MSXML and most likely ActiveDOM too. So no special considerations are needed for property values.

  • 2002-12-05

    The property bag now mangle the property names so that they never mess up the XML syntax. Two new interface functions added: SaveToStream and LoadFromStream. Useful if you keep your XML property bags in structured storages for example.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Jörgen Sigvardsson

Software Developer (Senior)

Sweden Sweden

Member

I make software.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
Questionre:biztalk server Pinmemberambatiushasri19:42 17 Oct '06  
AnswerRe: re:biztalk server PinmemberJoergen Sigvardsson21:46 17 Oct '06  
Questionerror 0x800A02E1 Pinmember12hugs8:16 21 May '06  
AnswerRe: error 0x800A02E1 Pinmemberrambo0076:15 6 Sep '06  
QuestionSamples Please? PinmemberChoppa6:34 13 Mar '03  
AnswerRe: Samples Please? PinmemberJörgen Sigvardsson11:09 13 Mar '03  
GeneralActiveX IpropertyBag: Get PARAM NAMES Pinmembersubramjobmail21:59 23 Feb '03  
GeneralRe: ActiveX IpropertyBag: Get PARAM NAMES Pinmemberandreshs121:59 8 May '03  
GeneralRe: ActiveX IpropertyBag: Get PARAM NAMES Pinmembersubramjobmail23:50 28 May '03  
GeneralRe: ActiveX IpropertyBag: Get PARAM NAMES Pinmemberandreshs123:59 1 Jun '03  
GeneralRe: ActiveX IpropertyBag: Get PARAM NAMES PinmemberThe Brett10:55 17 May '07  
GeneralI've got to see that PinmemberAndreas Saurwein23:44 2 Dec '02  
GeneralPoor swedish guys PinmemberJonathan de Halleux0:30 3 Dec '02  
GeneralRe: Poor swedish guys PinmemberAndreas Saurwein5:24 3 Dec '02  
GeneralRe: Poor swedish guys PinmemberJonathan de Halleux5:27 3 Dec '02  
GeneralRe: Snuss PinmemberHugo Hallman8:07 3 Dec '02  
GeneralRe: Snuss PinmemberJörgen Sigvardsson9:22 3 Dec '02  
GeneralRe: Snuss PinmemberJörgen Sigvardsson7:57 5 Dec '02  
GeneralRe: Poor swedish guys PinsussBeerfanatican21:11 2 Feb '03  
GeneralRe: Poor swedish guys PinmemberJonathan de Halleux23:26 2 Feb '03  
GeneralRe: I've got to see that PinmemberJörgen Sigvardsson9:24 3 Dec '02  
QuestionDon Box Code? PinmemberRene De La Garza12:33 2 Dec '02  
AnswerRe: Don Box Code? PinmemberJörgen Sigvardsson21:59 2 Dec '02  
AnswerRe: Don Box Code? PinmemberJörgen Sigvardsson22:06 2 Dec '02  
GeneralRe: Don Box Code? PinmemberRene De La Garza10:04 3 Dec '02  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web03 | 2.5.120517.1 | Last Updated 2 Dec 2002
Article Copyright 2002 by Jörgen Sigvardsson
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid