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? :) -panzi