web developer & system programmer

coder . cl

ramblings and thoughts on programming...


pyxser, the serialization model

published: 21-02-2009 / updated: 21-02-2009
posted in: projects, python, pyxser
by Daniel Molina Wegener

pyxser, my python-object to XML serializer, now has a complete serialization model with all the required XML strictness that a serializer needs but with a complete serialization flexibility to allow multiple kinds of objets to be serialized inside the XML document that it generates.

In the present post I will show the serialization model, based on a strict XML DTD to allow the given serialized document to be validated before the deserialization process:


<!--
    Copyright (c) 2009 Daniel Molina Wegener <dmw@coder.cl>

    This file is part of pyxser.

    pyxser is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    pyxser is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with pyxser.  If not, see <http://www.gnu.org/licenses/>.

    <!DOCTYPE pyxs:object
              PUBLIC "-//coder.cl//DTD pyxser 1.0//EN"
              "http://projects.coder.cl/pyxser/dtd/pyxser-1.0.dtd">
  -->

<!ENTITY % xml.xmlns "xmlns" >
<!ENTITY % pyxser.prefix "pyxs" >

<!ENTITY % pyxser.ns "%xml.xmlns;:%pyxser.prefix;" >

<!ENTITY % pyxser.object "object" >
<!ENTITY % pyxser.item "item" >
<!ENTITY % pyxser.collection "collection" >

<!ENTITY % pyxser.element.object "%pyxser.prefix;:%pyxser.object;" >
<!ENTITY % pyxser.element.item "%pyxser.prefix;:%pyxser.item;" >
<!ENTITY % pyxser.element.collection "%pyxser.prefix;:%pyxser.collection;" >

<!ENTITY % pyxser.attr.name "name" >
<!ENTITY % pyxser.attr.type "type" >
<!ENTITY % pyxser.attr.module "module" >
<!ENTITY % pyxser.attr.size "size" >
<!ENTITY % pyxser.attr.version "version" >
<!ENTITY % pyxser.attr.id "id" >
<!ENTITY % pyxser.attr.reference "reference" >
<!ENTITY % pyxser.attr.key "key" >
<!ENTITY % pyxser.attr.compress "compress" >
<!ENTITY % pyxser.attr.encoding "encoding" >

<!ELEMENT %pyxser.element.object;
          (%pyxser.element.item;
          | %pyxser.element.collection;
          | %pyxser.element.object;)* >

<!ATTLIST %pyxser.element.object;
          %pyxser.ns;                   CDATA           #FIXED          "http://projects.coder.cl/pyxser/model/"
          %pyxser.attr.version;         CDATA           #FIXED          "1.0"
          %pyxser.attr.id;              ID              #IMPLIED
          %pyxser.attr.reference;       IDREF           #IMPLIED
          %pyxser.attr.type;            NMTOKEN         #IMPLIED
          %pyxser.attr.name;            NMTOKEN         #IMPLIED
          %pyxser.attr.module;          NMTOKEN         #IMPLIED
          %pyxser.attr.size;            NMTOKEN         #IMPLIED
          %pyxser.attr.key;             CDATA           #IMPLIED
          >

<!ELEMENT %pyxser.element.collection;
          (%pyxser.element.object;
          | %pyxser.element.item;)* >

<!ATTLIST %pyxser.element.collection;
          %pyxser.attr.type;            NMTOKEN         #REQUIRED
          %pyxser.attr.name;            NMTOKEN         #REQUIRED
          >

<!ELEMENT %pyxser.element.item;
          (#PCDATA)
          >

<!ATTLIST %pyxser.element.item;
          %pyxser.attr.type;            NMTOKEN         #REQUIRED
          %pyxser.attr.name;            NMTOKEN         #REQUIRED
          %pyxser.attr.size;            NMTOKEN         #IMPLIED
          %pyxser.attr.key;             CDATA           #IMPLIED
          %pyxser.attr.compress;        (yes|no)        #IMPLIED
          %pyxser.attr.encoding;        (ascii|base64)  #IMPLIED
          >

the object element

The DOCTYPE FPI signs the XML tree root element as a pyxser object and sets the version and namespace attributes to fixed values — oh!, Micro$osft XML parser until version 5 wasn’t capable to catch fixed attributes, and I don’t know if the Micro$oft guys have fixed it, what a damn! ;) and then you ask me "why do you think that Micro$oft sucks?" — and it allows cross refernces between created objects by using id and reference attributes. The type and module attributes allows to set the class name and python module on the object. The name and key attributes, allows to identify the object inside another object or inside a dictionary-like collection.

The object element allow to recursively to nest more objects, and also insert collections and object properties as item elements.

the collection element

Collections are treated as XML sequences of items or object properties. It hold both primitive and more complex types like objects or collections. Also allows have name and type attributes to allow the identification of the property name inside the object and the collection type (dict, list, tuple). It isn’t declared as a DTD sequence of (dict|list|tuple), because there are more sub-typed collections that fits this spec and in this case, the developer is responsible to load the proper module to create the deserialized object, instead of objects, that have embeded the automatic loading of their declaration module in the deserialization routine.

the item element

The item element allows the storage of primitive types. The type attribute identifies the serialization type. The name and key attributes are used to identify them inside objects and dictionary-like collections. The buffer and file types are compressed and encoded into base64 on certain cases, and then the compress, encoding and size attributes are used. For str and unicode types, only the size attribute is used on the drawback of decoding the proper charset encoding. In pyxser, by default it’s used Unicode encoding, this means thast the decoding process will allow for example, members in UTF-16 encoding.


<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE pyxs:object PUBLIC "-//coder.cl//DTD pyxser 1.0//EN" "http://projects.coder.cl/pyxser/dtd/pyxser-1.0.dtd">
<pyxs:object xmlns:pyxs="http://projects.coder.cl/pyxser/model/" version="1.0" type="ParentObject" module="testpkg.sample" id="id-136814668">
  <pyxs:item type="unicode" name="dyn_prop4" size="21">sxf3mxe9 txe8xtxe8 xefxf1 Unicodxe8</pyxs:item>
  <pyxs:item type="unicode" name="dyn_prop5" size="24">Axf1other Texxe9 Ixf1 xdcnxeccxf3Dxcbc</pyxs:item>
  <pyxs:collection type="list" name="dyn_prop1">
    <pyxs:item type="unicode" name="item" size="4">holxe1</pyxs:item>
    <pyxs:item type="unicode" name="item" size="4">chaxf3</pyxs:item>
    <pyxs:object type="ParentObject" reference="id-136814668"/>
    <pyxs:object type="TestAnotherObject" module="__main__" id="id-136815468">
      <pyxs:item type="str" name="first_element">123</pyxs:item>
      <pyxs:item type="str" name="second_element">456</pyxs:item>
    </pyxs:object>
  </pyxs:collection>
  <pyxs:collection type="tuple" name="dyn_prop2">
    <pyxs:item type="unicode" name="item" size="4">hol`</pyxs:item>
    <pyxs:object type="ParentObject" reference="id-136814668"/>
    <pyxs:item type="unicode" name="item" size="3">sxefn</pyxs:item>
    <pyxs:item type="str" name="item">trip</pyxs:item>
  </pyxs:collection>
  <pyxs:object type="dict" name="dyn_prop3">
    <pyxs:item type="unicode" name="item" size="4" key="saludo1">hxf3lxe0</pyxs:item>
    <pyxs:object reference="id-136814668" key="saludo3"/>
    <pyxs:item type="unicode" name="item" size="4" key="saludo2">chxe4xf3</pyxs:item>
    <pyxs:item type="str" name="item" key="saludo4">goodbye</pyxs:item>
  </pyxs:object>
  <pyxs:object type="ChildObject" name="parent3" module="testpkg.sample" id="id-136815500">
    <pyxs:item type="str" name="child1">hi</pyxs:item>
    <pyxs:item type="float" name="child2">4.5</pyxs:item>
    <pyxs:item type="int" name="child3">2354</pyxs:item>
    <pyxs:object type="NestedChild" name="child4" module="testpkg.sample" id="id-136815532">
      <pyxs:object type="SubNestedChild" name="nested4" module="testpkg.sample" id="id-136815596">
        <pyxs:object type="ParentObject" name="subnested1" module="testpkg.sample" reference="id-136814668"/>
      </pyxs:object>
      <pyxs:item type="str" name="nested1" compress="no" encoding="ascii">holahola</pyxs:item>
      <pyxs:item type="int" name="nested2" compress="no" encoding="ascii">345</pyxs:item>
      <pyxs:item type="str" name="nested3" compress="no" encoding="ascii">hola</pyxs:item>
    </pyxs:object>
  </pyxs:object>
  <pyxs:item type="str" name="parent2">chao</pyxs:item>
  <pyxs:item type="str" name="parent1">hola</pyxs:item>
</pyxs:object>


one comment to “pyxser, the serialization model”

  1. Omg you are to the “dot” we are going to submit to Tweets as well as Tagged thanks pyxser, the serialization model — coder . cl is cool Anyway our prayers go out to those close by the tidal wave we hope you are ok plus free from danger !… Regards ! Online Website Builder

post a comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>