Tuesday 9 June 2009

XML and objects - my approach

So recently, I've been working on a project where I have the two extremes... a very complex tree structure in XML format and a very complex object structure in Python (which is incidentally mapped to an equally complex 56 table database using Elixir). The object structure would make no sense as a tree and XML doesn't work well as objects so I was left to consider alternatives.

My solution was to create a way of specifying the relationship between the XML nodes and the objects and created an XML schema language of sorts to do this (well, I created two, but the second one was more for completeness. I may mention it in a later blog post). I've unimaginatively called this schema the 'XML Object Mapping Schema' (XOMS for short) and a quick sample is as follows:

<xoms>
<person xoms_to="Person" name="Person.name">
<address xoms_to="Address" xoms_link="Person.address" xoms_content="Address.address">
</person>
</xoms>

It should be fairly obvious what the above should do. It says that a 'person' element should be mapped to a 'Person' object and it's 'name' attribute should be shoved into the 'Person.name' property. The 'address' node should similarly be mapped to an 'Address' object and the content of an 'address' element should be shoved into the 'Address.address' property. The xoms_link says that this Address object should then be linked to the Person.address property. So with this XML:

<person name="Joe Bloggs">
<address>
1 Somewhere drive, Someplace, Earth
</address>
</person>

would produce the following objects:

[<person name="Joe Bloggs" address="<Address address="...">" >, <Address address="...">]

with a Python implementation.

I've got a fair few more features than this now implemented in a Python library that allows automated object construction from XML to a fairly arbitrary object structure, including the ability to call functions on the objects with parameters take from subnodes (for when I can't manage what I need just with XOMS). It's not perfect but it's doing well enough to populate the above mentioned data models and it's a lot leaner than my original approach. With about 500 lines of code and about 100 lines of XML I've replaced the same amount of XML processing, except that my new approach is complete where my original code was only mapping about 10 objects and not all their attributes. If I'd gone down that road I'd have gotten a couple of thousand lines of code that would have been messing, horrible to maintain and impossible to see where everything was going. This way I have 500 lines of code that performs some magic and all of the interesting stuff is kept in the XOMS file where I can easily see what's happening and change it.

So I've now become guilty of that heinous crime - solving problems with XML by throwing more XML at it... this time it seems to have worked though!

No comments:

Post a Comment