Fog Creek Software
Discussion Board




Instant Object Hierarchies with MSXML?

I tried a new way (for me) to quickly create a set of objects with minimal coding and I want to know your opinion.

The idea is this:  Create an xml document that represents your object or set of objects (object model).  Create property let/get/set routines that directly access the xml using msxml objects and methods to carry out the desired functionality, all using the xml to store the state of the object.

Here is an example of a property routine using an attribute:

Public Property Get ID() As Long
    ID = moScriptEl.getAttribute(ATT_SCRIPTID)
End Property

Private Property Let ID(ByVal lNew As Long)
    moScriptEl.setAttribute ATT_SCRIPTID, lNew
End Property

Here is one using a sub-element at a known index:

Public Property Get Cmd() As String
    Cmd = moScriptEl.childNodes(TIDX_QRY).Text
End Property

Public Property Let Cmd(sVal As String)
    moScriptEl.childNodes(TIDX_QRY).Text = sVal
End Property

During Class_Initialize() I load a minimal representation of the xml representing this object and the client app sets properties etc.  You can save it to a document then load it back up or even save it to a database.

Also, in lieu of a Collection of objects I am thinking that an IXMLDOMNodeList is much more flexible albeit (slightly?) slower.

Similar techniques that I have tried include disconnected recordsets that you can save to a file/xml and using the PropertyBag object to persist to a file, but I found them both harder to encompass a hierarchy and do it quickly.

Anyway, I have never seen this done before and I was wondering what you think? 

Wayne
Tuesday, June 17, 2003

It sounds terribly inefficient and a bit of a pain to maintain all the property functions. Each property Let will take a ton of time compared to a regular assignment. Remember, an assignment statement boils down to one statement - MOV - in assembler. Changing a node in an XML tree is going to be several orders of magnitude slower.

I would just expose the properties as public members of your class, where they can be set and gotten directly, then write functions DumpToXML and LoadFromXML if you ever need to persist the object.

Joel Spolsky
Tuesday, June 17, 2003

MSXML parser is actually pretty slow for those types of operations. I would first switch the parser to non-validating mode.

I been using Chilkat XML parser, and it is much faster and easier to use than MSXML. Haven't looked back since I switched.

Their website is at http://www.chilkatsoft.com

Hector
Wednesday, June 18, 2003

I have built other classes using the DumpToXML/LoadFromXML persist method and I like it a lot. 

What prompted me to try it the new way was that I found myself building more classes to represent the hierarchy and I thought that msxml could do it better for me.

Of course you're right about the assembler.  I'm a *bad programmer* because I was looking for a shortcut (not having to manage any of my own data-structures).  That's what they get for wanting everything yesterday!

I'm so lazy :)  Thanks for your reply.

Wayne
Wednesday, June 18, 2003

You might consider writing a code generator for this sort of stuff.

as part of MSXML comes the SOM library - schema object modell - this is a class library for accessing xml schema definitions.
You might traverse the schema definition (if there is one) and create get set methods for each element/attribute.

Michael Moser
Wednesday, June 18, 2003

in continuation ...

<shameless_selfpromotion>

.. gode generator like this would be something i could do as contractor.

You might contact me via this mail form

http://www.michaelmoser.org/mailme/mailme.pl


</shameless_selfpromotion>

Michael Moser
Wednesday, June 18, 2003

I’m confused.

Are you trying to build your property methods using a schema or are you using MSXML to hold all the properties internally, accessing them through a single ‘Get’ ?

Assuming the latter, I don’t understand ATT_SCRIPTID and TIDX_QRY. Where do these get set? What do they represent? If these values hold xpath queries, make sure they don’t parse the whole document (i.e. make sure they don’t have // at the start).

Try:
    moScriptEl.selectSingleNode(….).text

Joel is correct in saying that it will be slower, but speed may not be your main criterion for choosing this architecture (Laziness, right?).

Justin
Wednesday, June 18, 2003

ATT_SCRIPTID is a string constant holding the name of the attribute, TIDX_QRY is a long constant holding the index of a sub-element.

As for xpath, I usually make the queries relative.

Joel is right though, because even though it's nice to not have to declare any internal variables, the combination of speed loss and harder maintenance make it less attractive.

I will have to do some speed and memory tests though to see the difference between a type-array an object-collection and an IXMLDOMNodeList or IXMLDOMElement.

Wayne
Wednesday, June 18, 2003

I actually do something like this but I generate the wrapper classes and accessor methods using an xslt.  Its how I store hierarchical configuration information. 

B
Wednesday, June 18, 2003

For the GET side, you might want to consider working in .NET if you're a big fan of this sort of thing. We have dozens upon dozens of classes marked with [XmlAttribute] etc, which can be Serialize()d and Deserialize()d whenever you like.

J
Wednesday, June 18, 2003

As J says, if you are using .NET, LoadFromXML and DumpToXML are redundant as you can use the XmlSerializer class to serialise and deserialise object state direct from XML (sourced from a file or database, for example).

I've found it very useful when using MSMQ for asynchronous communication, simply serialising and deserialsing object state from the queue.

Pietro
Thursday, June 19, 2003

*  Recent Topics

*  Fog Creek Home