views:

306

answers:

3

I have some IronPython code which makes use of XmlTextWriter which allows me to write code like

self.writer = System.Xml.XmlTextWriter(filename, None)
self.writer.Formatting = Formatting.Indented
self.writer.WriteStartElement(name)
self.writer.WriteString(str(text))
self.writer.WriteEndElement()

...

self.writer.Close()

I would like to make my code portable across Python implementations (CPython, IronPython and Jython). Is there a streaming Python XML writer I can use for this without needing to use either print statements, or to construct a whole DOM tree before writing it out to file?

+2  A: 

I've never used the .NET implementation you're talking about, but it sounds like the closest you're going to get is Python's SAX parser (specifically, the XMLGenerator class -- some sample code here).

musicfreak
Specifically, xml.sax.saxutils.XMLGenerator, which is part of sax but not really a parser.
Matthew Flaschen
Yes, thanks for pointing that out.
musicfreak
+1  A: 

I wrote a tool to facilitate XML generation from Python (code and tutorial)

Bill Zeller
"I a tool"? What does that mean? ;)
musicfreak
Editing issues :-) Thanks.
Bill Zeller
No problem. +1, looks like a good tool, and great name.
musicfreak
Most elegant. Can you provide an example of how this would be used in the case where I don't know the element names until run time?
Rob Smallshire
It assumes the element names are known so it sounds like it doesn't solve your problem. (Well, you could write something like x = XMLegant() element_name = "root" el = getattr(x, element_name)but that seems to defeat the point.)
Bill Zeller
+1  A: 

I wrote a module named loxun to do just that: http://pypi.python.org/pypi/loxun/. It runs with CPython 2.5 and Jython 2.5, but I never tried it with IronPython.

Example usage:

with open("...", "wb") as out:
  xml = XmlWriter(out)
  xml.addNamespace("xhtml", "http://www.w3.org/1999/xhtml")
  xml.startTag("xhtml:html")
  xml.startTag("xhtml:body")
  xml.text("Hello world!")
  xml.tag("xhtml:img", {"src": "smile.png", "alt": ":-)"})
  xml.endTag()
  xml.endTag()
  xml.close()

And the result:

<?xml version="1.0" encoding="utf-8"?>
<xhtml:html xlmns:xhtml="http://www.w3.org/1999/xhtml"&gt;
  <xhtml:body>
    Hello world!
    <xhtml:img alt=":-)" src="smile.png" />
  </xhtml:body>
</xhtml:html>

Among other features, it detects missalligned tags while you write, uses a streaming API with a small memory footprint, supports Unicode and allows to disable pretty printing.