web developer & system programmer

coder . cl

ramblings and thoughts on programming...


pyxser, a finished serializer

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

pyxser, my python-object to XML serializer, it’s now finished. I’ve added support for unicode objects and set the default encoding to utf-8. Also I have added the proper namespace and profiled the resulting serializer. It continues as O(n) serializing algorithm.

If we continue with our last example, we have sample called testpkg.sample:


__all__ = [
    'SubNestedChild',
    'NestedChild',
    'ChildObject',
    'ParentObject']

class SubNestedChild:
    subnested1 = None
    def __init__(self, m1):
        self.subnested1 = m1

class NestedChild:
    nested1 = None
    nested2 = None
    nested3 = None
    nested4 = None
    def __init__(self, m1, m2, m3):
        self.nested1 = m1
        self.nested2 = m2
        self.nested3 = m3

class ChildObject:
    child1 = None
    child2 = None
    child3 = None
    child4 = None
    def __init__(self, m1, m2, m3):
        self.child1 = m1
        self.child2 = m2
        self.child3 = m3

class ParentObject:
    parent1 = None
    parent2 = None
    parent3 = None
    def __init__(self, m1, m2, m3):
        self.parent1 = m1
        self.parent2 = m2
    def child(self, m1, m2, m3):
        self.parent3 = ChildObject(m1, m2, m3)
    def nested(self, m1, m2, m3):
        self.parent3.child4 = NestedChild(m1, m2, m3)
    def subnested(self, m1):
        self.parent3.child4.nested4 = SubNestedChild(m1)

And a sample application with some tricky object properties/attributes:

#!/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 = [u"holá", u"chaó", test, another]
    test.dyn_prop2 = (u"hol`", test, u"sïn", "trip")
    test.dyn_prop3 = {"saludo1": u"hólà", "saludo2": u"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 serialization, it’s the next piece of XML:


<?xml version="1.0" encoding="utf-8"?>
<pyxs:ParentObject xmlns:pyxs="http://coder.cl/pyxser/model/" version="1.0" module="testpkg.sample" id="136624428">
  <pyxs:dyn_prop4 type="unicode" size="21">sxf3mxe9 txe8xtxe8 xefxf1 Unicodxe8</pyxs:dyn_prop4>
  <pyxs:dyn_prop5 type="unicode" size="24">Axf1other Texxe9 Ixf1 xdcnxeccxf3Dxcbc</pyxs:dyn_prop5>
  <pyxs:dyn_prop1 type="list">
    <pyxs:item type="unicode" size="4">holxe1</pyxs:item>
    <pyxs:item type="unicode" size="4">chaxf3</pyxs:item>
    <pyxs:ParentObject reference="#136624428" name="ParentObject"/>
    <pyxs:TestAnotherObject module="__main__" id="136625228">
      <pyxs:first_element type="str">123</pyxs:first_element>
      <pyxs:second_element type="str">456</pyxs:second_element>
    </pyxs:TestAnotherObject>
  </pyxs:dyn_prop1>
  <pyxs:dyn_prop2 type="tuple">
    <pyxs:item type="unicode" size="4">hol`</pyxs:item>
    <pyxs:ParentObject reference="#136624428" name="ParentObject"/>
    <pyxs:item type="unicode" size="3">sxefn</pyxs:item>
    <pyxs:item type="str">trip</pyxs:item>
  </pyxs:dyn_prop2>
  <pyxs:dyn_prop3 type="dict">
    <pyxs:item type="unicode" size="4" key="saludo1">hxf3lxe0</pyxs:item>
    <pyxs:ParentObject reference="#136624428" name="ParentObject" key="saludo3"/>
    <pyxs:item type="unicode" size="4" key="saludo2">chxe4xf3</pyxs:item>
    <pyxs:item type="str" key="saludo4">goodbye</pyxs:item>
  </pyxs:dyn_prop3>
  <pyxs:ChildObject module="testpkg.sample" id="136625260">
    <pyxs:child1 type="str">hi</pyxs:child1>
    <pyxs:child2 type="float">4.5</pyxs:child2>
    <pyxs:child3 type="int">2354</pyxs:child3>
    <pyxs:NestedChild module="testpkg.sample" id="136625292">
      <pyxs:SubNestedChild module="testpkg.sample" id="136625356">
        <pyxs:ParentObject module="testpkg.sample" reference="#136624428" name="subnested1"/>
      </pyxs:SubNestedChild>
      <pyxs:nested1 type="str">holahola</pyxs:nested1>
      <pyxs:nested2 type="int">345</pyxs:nested2>
      <pyxs:nested3 type="str">hola</pyxs:nested3>
    </pyxs:NestedChild>
  </pyxs:ChildObject>
  <pyxs:parent2 type="str">chao</pyxs:parent2>
  <pyxs:parent1 type="str">hola</pyxs:parent1>
</pyxs:ParentObject>

Everything seems to be ok. Why I’ve used escaped unicode?. It’s simple, the supported encodings by libxml2 it’s limited to some encodings and do not have the same support that iconv have. Then, if someone sends an unicode string under Python that is encoded in utf-32, we can get some errors by getting the XML serialization encoded in utf-8. Well, I think that pyxser as object serializer is a faster one ;)


         40 function calls in 0.004 CPU seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.004    0.004 <string>:1(<module>)
        1    0.000    0.000    0.000    0.000 __init__.py:1(<module>)
        1    0.000    0.000    0.000    0.000 __init__.py:48(normalize_encoding)
        1    0.000    0.000    0.000    0.000 __init__.py:70(search_function)
        1    0.000    0.000    0.000    0.000 codecs.py:77(__new__)
        1    0.000    0.000    0.000    0.000 sample.py:11(__init__)
        1    0.000    0.000    0.000    0.000 sample.py:14(NestedChild)
        1    0.000    0.000    0.000    0.000 sample.py:19(__init__)
        1    0.000    0.000    0.000    0.000 sample.py:24(ChildObject)
        1    0.000    0.000    0.000    0.000 sample.py:29(__init__)
        1    0.000    0.000    0.000    0.000 sample.py:34(ParentObject)
        1    0.000    0.000    0.000    0.000 sample.py:38(__init__)
        1    0.000    0.000    0.000    0.000 sample.py:4(<module>)
        1    0.000    0.000    0.000    0.000 sample.py:41(child)
        1    0.000    0.000    0.000    0.000 sample.py:43(nested)
        1    0.000    0.000    0.000    0.000 sample.py:45(subnested)
        1    0.000    0.000    0.000    0.000 sample.py:9(SubNestedChild)
        1    0.002    0.002    0.003    0.003 test.py:4(<module>)
        1    0.000    0.000    0.000    0.000 test.py:7(TestAnotherObject)
        1    0.000    0.000    0.000    0.000 utf_16_be.py:18(IncrementalEncoder)
        1    0.000    0.000    0.000    0.000 utf_16_be.py:22(IncrementalDecoder)
        1    0.000    0.000    0.000    0.000 utf_16_be.py:25(StreamWriter)
        1    0.000    0.000    0.000    0.000 utf_16_be.py:28(StreamReader)
        1    0.000    0.000    0.000    0.000 utf_16_be.py:33(getregentry)
        1    0.000    0.000    0.000    0.000 utf_16_be.py:8(<module>)
        1    0.000    0.000    0.000    0.000 {__import__}
        1    0.000    0.000    0.000    0.000 {built-in method __new__ of type object at 0x810f1c0}
        1    0.000    0.000    0.004    0.004 {execfile}
        1    0.000    0.000    0.000    0.000 {globals}
        1    0.000    0.000    0.000    0.000 {isinstance}
        1    0.000    0.000    0.000    0.000 {locals}
        1    0.000    0.000    0.000    0.000 {method "disable" of "_lsprof.Profiler" objects}
        3    0.000    0.000    0.000    0.000 {method "get" of "dict" objects}
        1    0.000    0.000    0.000    0.000 {method "join" of "str" objects}
        1    0.000    0.000    0.000    0.000 {method "replace" of "str" objects}
        1    0.000    0.000    0.000    0.000 {method "split" of "str" objects}
        1    0.000    0.000    0.000    0.000 {method "translate" of "str" objects}
        1    0.001    0.001    0.001    0.001 {pyxser.serialize_xml}

My TODO list for pyxser now it’s as follows:

  1. Develop the pyxser deserializer.
  2. Make a complete code cleanup of the pyxser serializer.
  3. Optimize the serializer.
  4. Make a complete code cleanup of the pyxser deserializer.
  5. Optimize the deserializer.

And pyxser will be published and released as beta when the first point will be finished. I hope that you will enjoy and test this extension, and also I hope that you will be contributing to it’s development.


one comment to “pyxser, a finished serializer”

  1. [...] "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 [...]

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>