Package pyxslt :: Module serialize
[frames | no frames]

Module pyxslt.serialize

Convert a tree of Python objects into an XML document.

Overview

The functions in this module can convert one or more Python objects into libxml2.xmlDoc object. This is performed by the toString function, which takes a list of Python objects and returns an XML document (wrapped in a <pyxslt>..</pyxslt> tag, although the root tag name can be changed).

All objects given to the serialization function must be able to return their value as a string. pyxslt will iterate through list, tuples, and dictionaries. In addition, pyxslt knows about SQLObject instances and will serialize the contents of all of the columns in the object. sqlobject.ForeignKey and sqlobject.MultipleJoin references will be traversed as well.

Basic Serialization

Here is a simple example of encoding a handful of Python objects:
>>> print toString(prettyPrintXml=True,
...     firstName='Michael Alyn',
...     lastName='Miller',
...     oneTwoThree=123,
...     myURL='http://www.strangeGizmo.com/',
... ),
<?xml version="1.0" encoding="ASCII"?>
<pyxslt>
  <last-name>Miller</last-name>
  <my-url>http://www.strangeGizmo.com/</my-url>
  <first-name>Michael Alyn</first-name>
  <one-two-three>123</one-two-three>
</pyxslt>

Note that the keyword names (firstName, lastName, oneTwoThree, etc.) were converted to "XML-style" names (first-name, last-name, one-two-three) as part of the serialization process. Complete documentation for this transformation can be found in the documentation for the names.pythonNameToXmlTag function.

It should also be pointed out that the serialization process does not preserve the order of the Python objects given to the serialize function.

Dictionaries

>>> print toString(prettyPrintXml=True,
...     foo='bar',
...     props={
...         'propA': 1,
...         'propB': 2,
...         'propC': (3, 4, 5),
...         'propD': { 'six': 6, 'seven': 7, 'eight': 8 },
...     },
... ),
<?xml version="1.0" encoding="ASCII"?>
<pyxslt>
  <foo>bar</foo>
  <props>
    <item key="propD">
      <item key="seven">7</item>
      <item key="six">6</item>
      <item key="eight">8</item>
    </item>
    <item key="propA">1</item>
    <item key="propB">2</item>
    <item key="propC">
      <item>3</item>
      <item>4</item>
      <item>5</item>
    </item>
  </props>
</pyxslt>

Lists and Tuples

>>> print toString(prettyPrintXml=True,
...     foo='bar',
...     listOfNumbers=(
...         1,
...         2,
...     ),
... ),
<?xml version="1.0" encoding="ASCII"?>
<pyxslt>
  <list-of-numbers>
    <item>1</item>
    <item>2</item>
  </list-of-numbers>
  <foo>bar</foo>
</pyxslt>
pyxslt accepts Python objects as both positional arguments and keyword arguments. These objects must contain embedded names so that pyxslt can create XML tags for those objects.

Complex Serialization

Complex example:
>>> class A(object): pass
...
>>> a = A()
>>> a.foo = 1
>>> a.bar = 2
>>> a.baz = [1, 2, 3]
>>> a.faz = { 'one': 1, 'two': 2, 'three': '1&2' }
>>> a.b = A()
>>> a.b.eleven = 11
>>> a.b.twelve = 12
>>> firstObj = A()
>>> firstObj.isFirst = True
>>> secondObj = A()
>>> secondObj.isFirst = False
>>> a.objList = { 'first': firstObj, 'second': secondObj }
>>> print toString(prettyPrintXml=True,
...     myObject=a,
... ),
<?xml version="1.0" encoding="ASCII"?>
<pyxslt>
  <my-object>
    <faz>
      <item key="three">1&amp;2</item>
      <item key="two">2</item>
      <item key="one">1</item>
    </faz>
    <b>
      <eleven>11</eleven>
      <twelve>12</twelve>
    </b>
    <bar>2</bar>
    <obj-list>
      <item key="second">
        <is-first>False</is-first>
      </item>
      <item key="first">
        <is-first>True</is-first>
      </item>
    </obj-list>
    <baz>
      <item>1</item>
      <item>2</item>
      <item>3</item>
    </baz>
    <foo>1</foo>
  </my-object>
</pyxslt>

SQLObject Examples

First we initialize SQLObject and create a few sample tables:
>>> # Import SQLObject.
>>> try:
...     import pkg_resources
...     ignore = pkg_resources.require('SQLObject>=0.7')
... except:
...     pass
>>> from sqlobject import *
...
>>> # Create an in-memory SQLite database.
>>> sqlhub.processConnection = connectionForURI('sqlite:/:memory:')
...
>>> # Define the database classes.
>>> class Person(SQLObject):
...     firstName = StringCol()
...     middleInitial = StringCol(length=1, default=None)
...     lastName = StringCol()
...     website = ForeignKey('URL', default=None)
...     phoneNumbers = MultipleJoin('PhoneNumber')
>>> class PhoneNumber(SQLObject):
...     person = ForeignKey('Person')
...     phoneType = EnumCol(enumValues=['voice', 'fax', 'cell'])
...     countryCode = IntCol(default=1)
...     number = StringCol()
>>> class URL(SQLObject):
...     address = StringCol()
...
>>> # Create the tables.
>>> Person.createTable()
>>> PhoneNumber.createTable()
>>> URL.createTable()
Then we create some table entries:
>>> # Michael Alyn Miller
>>> malyn = Person(firstName='Michael Alyn', lastName='Miller')
>>> malyn.website = URL(address='http://www.strangeGizmo.com/')
>>> mv = PhoneNumber(person=malyn, phoneType='voice', number='555-1212')
>>> mc = PhoneNumber(person=malyn, phoneType='cell', number='123-4567')
...
>>> # Bob F. Bar
>>> bob = Person(firstName='Bob', middleInitial='F', lastName='Bar')
>>> bv = PhoneNumber(person=bob, phoneType='voice', number='262-2620')
Now we serialize the entries:
>>> print toString(prettyPrintXml=True,
...     person=malyn,
... ),
<?xml version="1.0" encoding="ASCII"?>
<pyxslt>
  <person id="1">
    <first-name>Michael Alyn</first-name>
    <last-name>Miller</last-name>
    <website id="1">
      <address>http://www.strangeGizmo.com/</address>
    </website>
    <phone-numbers>
      <item id="1">
        <phone-type>voice</phone-type>
        <country-code>1</country-code>
        <number>555-1212</number>
      </item>
      <item id="2">
        <phone-type>cell</phone-type>
        <country-code>1</country-code>
        <number>123-4567</number>
      </item>
    </phone-numbers>
  </person>
</pyxslt>
Notice that the Person table is included when a PhoneNumber is serialized directly (rather than as a MultipleJoin from a Person object):
>>> print toString(prettyPrintXml=True,
...     phoneNumber=mv,
... ),
<?xml version="1.0" encoding="ASCII"?>
<pyxslt>
  <phone-number id="1">
    <person id="1">
      <first-name>Michael Alyn</first-name>
      <last-name>Miller</last-name>
      <website id="1">
        <address>http://www.strangeGizmo.com/</address>
      </website>
      <phone-numbers>
        <item id="1">
          <phone-type>voice</phone-type>
          <country-code>1</country-code>
          <number>555-1212</number>
        </item>
        <item id="2">
          <phone-type>cell</phone-type>
          <country-code>1</country-code>
          <number>123-4567</number>
        </item>
      </phone-numbers>
    </person>
    <phone-type>voice</phone-type>
    <country-code>1</country-code>
    <number>555-1212</number>
  </phone-number>
</pyxslt>
This behavior is not always desired and could result in a large number of returned, serialized rows. To exclude one or more SQL relationship from the serialized result, pass a list of (dbClass, attrName) tuples to the ignoreRelationship keyword argument:
>>> print toString(prettyPrintXml=True,
...     ignoreRelationship=[(PhoneNumber, 'person')],
...     phoneNumber=mv,
... ),
<?xml version="1.0" encoding="ASCII"?>
<pyxslt>
  <phone-number id="1">
    <person>1</person>
    <phone-type>voice</phone-type>
    <country-code>1</country-code>
    <number>555-1212</number>
  </phone-number>
</pyxslt>
This functionality can also be used if you want to output the results of an SQLObject query, but do not want to descend into a specific MultipleJoin:
>>> print toString(prettyPrintXml=True,
...     ignoreRelationship=[(Person, 'phoneNumbers')],
...     phoneList=Person.select(),
... ),
<?xml version="1.0" encoding="ASCII"?>
<pyxslt>
  <phone-list>
    <item id="1">
      <first-name>Michael Alyn</first-name>
      <last-name>Miller</last-name>
      <website id="1">
        <address>http://www.strangeGizmo.com/</address>
      </website>
    </item>
    <item id="2">
      <first-name>Bob</first-name>
      <middle-initial>F</middle-initial>
      <last-name>Bar</last-name>
    </item>
  </phone-list>
</pyxslt>
Note that ignored MultipleJoin relationship do not appear at all in the output tree, whereas ignored ForeignKey relationships will include a node containing the id of the related row.

Author: Michael Alyn Miller <malyn@strangeGizmo.com>

Copyright: 2006 by Michael Alyn Miller

License: BSD License (see source code for full license)

Classes
Serializer Serializes Python objects to XML documents.

Function Summary
str toString(rootTagName, encoding, prettyPrintXml, ignoreRelationship, **elements)
Serialize a dictionary of Python objects to an XML document and return the textual version of the document.

Function Details

toString(rootTagName='pyxslt', encoding='ASCII', prettyPrintXml=False, ignoreRelationship=[], **elements)

Serialize a dictionary of Python objects to an XML document and return the textual version of the document.
Parameters:
rootTagName - The name of the XML tag that will enclose the serialized Python objects.
           (type=str)
encoding - The character encoding to use when outputting the final XML document. Values such as UTF-8, ISO-8859-1, ASCII, etc. are appropriate.
           (type=str)
prettyPrintXml - True to indent the final XML output, False to return the bare XML without any extraneous spaces or linefeeds.
           (type=bool)
Returns:
The given Python objects as an XML document.
           (type=str)

Generated by Epydoc 2.1 on Wed Jul 12 11:19:10 2006 http://epydoc.sf.net