[Python-ideas] xml generator that uses the with statement

Josiah Carlson josiah.carlson at gmail.com
Sat Sep 13 01:38:44 CEST 2008


On Fri, Sep 12, 2008 at 3:57 PM, Mathias Panzenböck
<grosser.meister.morti at gmx.net> wrote:
> Here is a quick and dirty draft of a xml generator that uses the with statement:
> http://twoday.tuwien.ac.at/pub/files/XmlMarkup (ZIP, 3 KB)
>
> It is inspired by rubies XmlMarkup class.
>
> Brief usage:
>>>> from __future__ import with_statement
>>>> from XmlMarkup  import *
>>>> import sys
>>>>
>>>> with XmlMarkup(sys.stdout) as xm:
>>>>     with xm.root:
>>>>             xm.text('foo')
>>>>             with xm.prefixMapping('x','http://example.com/x'):
>>>>                     with xm.tag.ns('http://example.com/x'):
>>>>                             xm.comment('comment')
>>>>                     with xm['text']:
>>>>                             xm.text('bar')
>>>>             with xm.tag(foo='bar',egg='spam'):
>>>>                     pass
> <?xml version="1.0" encoding="utf-8"?>
> <root>foo<x:tag
> xmlns:x="http://example.com/x"><!--comment--></x:tag><text>bar</text><tag
> foo="bar" egg="spam"></tag></root>
>
> I'm not 100% sure about some parts of the 'syntax', though.
> E.g. maybe change this:
>
>>>> with xm.tag(x='y').ns('...'):
>>>>     with xm.tag:
>>>>             ...
>
> into this:
>
>>>> with xm.tag('...',x='y'):
>>>>     with xm.tag():
>>>>             ...
>
>
>
> This Syntax is more concise than those unhandy and error prone
> beginElement/endElement calls (endElement needs the name as argument, too!).
> This way you never forget to close a tag again. :)
>
> It even provides a simple way to embed arbitrary data:
>
>>>> with xm.text as text:
>>>>     # text is a pseudo file object
>>>>     with XmlMarkup(text) as xm2:
>>>>             # things you generate with xm2 will be escaped
>
> And I added a way to generate DTDs:
>
>>>> with xm.dtd('foo') as dtd:
>>>>     dtd.element('a',oneof('x','y',PCDATA))
>>>>     dtd.element('x',('egg','bacon',many('spam')))
>>>>     dtd.attlist('a',att1 = (CDATA, DEFAULT, 'value'), att2 = (ID, REQUIRED))
>>>>     dtd.entity('ent','value')
>
>
> What do you think? :)

I've done a similar thing using with (and for in Python 2.4 or before)
in constructing wxPython GUI widget layouts.

 - Josiah



More information about the Python-ideas mailing list