web developer & system programmer

coder . cl

ramblings and thoughts on programming...


pyxser, serialization redesign and becoming strict

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

In my last posts: "pyxser, a work in progress", "pyxser, serializing collections" and "pyxser, a work in progress". I’ve signing that I have finished my python-object to XML serializer. Today I’ve redesigned the serialized, but preserving the O(n) serialization algorithm. Now, I have more strict way to create the XML documents. I’ve created a small XML DTD as follows:

<!ENTITY % pyxser.version "-//coder.cl//DTD pyxser 1.0//EN" >

<!ENTITY % pyxser.ns "xmlns:pyxs" >
<!ENTITY % pyxser.element.object "pyxs:object" >
<!ENTITY % pyxser.element.item "pyxs:item" >
<!ENTITY % pyxser.element.collection "pyxs: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" >

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

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

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

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

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

<!ATTLIST %pyxser.element.item;
          %pyxser.attr.type;            CDATA   #REQUIRED
          %pyxser.attr.name;            CDATA   #REQUIRED
          %pyxser.attr.size;            CDATA   #IMPLIED
          %pyxser.attr.key;             CDATA   #IMPLIED
          >

And now, the python-object serialization have the next result, as seen in my last post, we have single object to serialize:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import pyxser
import testpkg.sample

class TestAnotherObject:
    first_element = "123"
    second_element = "456"

if __name__ == "__main__":
    another = TestAnotherObject()
    another.first_element = "123"
    another.second_element = "456"
    test = testpkg.sample.ParentObject("hola", "chao", 2354345L)
    test.child("hi", 4.5, 2354)
    test.nested("holahola", 345, "hola")
    test.subnested(test)
    test.dyn_prop1 = ['holá', 'chaó', test, another]
    test.dyn_prop2 = ('hol`', test, 'sïn', 'trip')
    test.dyn_prop3 = {'saludo1': 'hòlá', 'saludo2': 'chäó', 'saludo3': test, 'saludo4': 'goodbye'}
    test.dyn_prop4 = u'sómé tèxtè ïñ Unicodè'
    test.dyn_prop5 = u'Añother Texé Iñ ÜnìcóDËc'
    print pyxser.serialize_xml(test)

The resulting XML now conforms the XML DTD defined for serialized python-objects and isn’t a tag salad as many XML that we can see on closed source software.

<?xml version="1.0" encoding="utf-8"?>
<pyxs:object xmlns:pyxs="http://coder.cl/pyxser/model/" version="1.0" type="ParentObject" module="testpkg.sample" id="id-136624428">
  <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-136624428"/>
    <pyxs:object type="TestAnotherObject" module="__main__" id="id-136625228">
      <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-136624428"/>
    <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-136624428" 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-136625260">
    <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-136625292">
      <pyxs:object type="SubNestedChild" name="nested4" module="testpkg.sample" id="id-136625356">
        <pyxs:object type="ParentObject" name="subnested1" module="testpkg.sample" reference="id-136624428"/>
      </pyxs:object>
      <pyxs:item type="str" name="nested1">holahola</pyxs:item>
      <pyxs:item type="int" name="nested2">345</pyxs:item>
      <pyxs:item type="str" name="nested3">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>

And using a single XML validator, without a tag soup or tag salad that many closed source software have on many companies that I’ve seen — as the Micro$oft web.config and app.config files when you add some custom extensions — and we have the needed strictness to create the proper XML Schema arround our serializer.

[XXX@quake /work/XXX/c/pyxser]$ xmllint --noout --dtdvalid ./src/pyxser.dtd test.xml
[XXX@quake /work/XXX/c/pyxser]$

I know that XML DTD isn’t a great job, but have some sense on validating the document. I need to create the proper DTD and the proper XML Schema, and I know that I have a good base on that ;)


2 comments to “pyxser, serialization redesign and becoming strict”

  1. [OT] WTF!?!?!, my site looks really ugly under IE7, but I can see the proper rendering under knoqueror, firefox, safari and opera. Who’s wrong? xD, I think that IE7 sucks ;)

    Well, I was thinking that a w3c valid css was enough to supply the ugly hacks that IE browsers family needs, but I’m wrong. Internet Explorer, aka IE* really sucks, it’s another headache yo my free time.

  2. [...] user, you may know that it uses a standard and structured serialization model. It was designed on January of 2009, and his target from that date until today is to generate a universal serialization model, so it [...]

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>