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:
- Develop the pyxser deserializer.
- Make a complete code cleanup of the pyxser serializer.
- Optimize the serializer.
- Make a complete code cleanup of the pyxser deserializer.
- 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.
[...] "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 [...]