Norbert Hartl

mostly brackets and pipes

XML Binding for Magritte

A very late blog post. It is a really long time since I started the XML Binding for magritte project. I always planned to do a short blog post to at least announce it somehow. In the meantime I used it quite a lot and it works for me very well. If you are used to mangle magritte descriptions you can unveal some of the secret powers. A lot of work on the code has been done by Jan van de Sandt.

Magritte is a framework that allows you to meta-describe your model. Meta describing contains extra information of all sorts like types, constraints and relationships. The relationships of objects can be mapped on a XML schema. The XML binding for magritte is not targetted towards serializing whole object graphs. For this I use Sixx. The XML Binding is useful where simple objects need a simple mapping onto XML in a cross-language and cross-platform manner (call it internet :) ). I started the project because I do a lot of REST APIs. In a REST way of doing things you wouldn’t nest objects over multiple levels. Only composite objects would be contained nested in their containing objects. Aggregated objects would be referenced by their own URI. how to use:

Let’s assume a test class MXSimpleObject (the class is contained in the tests of the package)

MXObject subclass: #MXSimpleObject 
   instanceVariableNames: 'title abstract date'  
   classVariableNames: ''   
   poolDictionaries: ''  
   category: 'Magritte-XMLBinding-Test'

We have three instance variables that should be mapped to XML.(btw. in this example the test class inherits from MXObject. This is not necessary to use the XML binding it just eases some things like this demo)

Every variable needs a getter and a setter.

title  
   ^ title

title: aString   
   title := aString

generate getters and setters for the other two variables as well. Now we first add magritte descriptions for the instance variables.

descriptionTitle 
   ^ MAStringDescription new     
      accessor: #title;    
      priority: 100;    
      label: ''Title'';    
      yourself

descriptionAbstract   
   ^ MAStringDescription new     
      accessor: #abstract;    
      priority: 150;    
      label: 'Abstract';    
      yourself

descriptionDate 
   ^ MADateDescription new    
      accessor: #date;     
      priority: 350;    
      label: 'Date';     
      yourself

Now we have described our object with magritte. In order to add the XML mapping to the object we need to alter the magritte descriptions. We decide that the title should be title and date should be an attribute and abstract should be an element. To tell the XML Binding we want an attribute add beXmlAttribute to the magritte description. The name of the xml entity (attribute name or element name) is taken from the accessor selector (accessor #date will lead to an entity name ‘date’). The names of the entities can be changed. To give the attribute a different name add xmlAttributeName: to the description. If we want it to be an element we just add beXmlElement to the description. To change the name of the element add xmlElementName: to the description. The resulting descriptions look like this

descriptionTitle 
   ^ MAStringDescription new     
      accessor: #title;    
      priority: 100;    
      label: ''Title'';    
      beXmlAttribute;      
      yourself

descriptionAbstract   
   ^ MAStringDescription new     
      accessor: #abstract;    
      priority: 150;    
      label: ''Abstract'';    
      beXmlElement;     
      yourself

descriptionDate 
   ^ MADateDescription new    
      accessor: #date;     
      priority: 350;    
      label: 'Date';     
      beXmlAttribute;      
      yourself

Finally we want the XML Element that is produced to be named “simpleobject”. For this we add a class side method

xmlElementName  
   ^ 'simpleobject'

We can now test if it works. Open a workspace and enter

MXSimpleObject description toXml: (   
   MXSimpleObject new      
      title: ''my demo binding'';      
      date: DateAndTime now;     
      abstract: 'this is just a demo about xml binding for magritte')

and you get

<simpleobject title="my demo binding" date="2011-05-25T18:38:05+02:00">  
   <abstract>this is just a demo about xml binding for magritte</abstract>
</simpleobject>

To be really useful we need to do a roundtrip test. Copy the produced string and recreate the object with

MXSimpleObject description fromXml: '<simpleobject title="my demo binding" date="2011-0525T18:38:05+02:00">      
<abstract>this is just a demo about xml binding for magritte</abstract> </simpleobject>'

and you should get an object back this is the same as the one we’ve started with.The XML Binding can deal with one-to-one and one-to-many relationships. There is enough testing code in the package that shows how it works. If you want to play with it you can get it from Lukas’ source site. Just load the

ConfigurationsOfMagritteAddOns2Gofer new   
   renggli: 'magritte2addons'; 
   package: 'ConfigurationOfMagritteAddOns2'; 
   load

followed by a

((Smalltalk at: #ConfigurationOfMagritteAddOns2)    
   project latestVersion) load: 'Magritte-XMLBinding'

Comments