I’m writing this post in response to a challenge. I wrote a post entitled Jython on Google AppEngine: Why bother?, which was a reply to a statement made by a Google engineer about not seeing the point of running jython on AppEngine. And a similar statement was repeated in a comment on that blog post (i.e. “the gist of what I intended to say was that while it was possible to run Jython on App Engine, I couldn’t think why you’d want to.”)
So rather than get into a back-and-forth of yes-it-is-no-it-isnt-yes-it-is, I thought I’d reply with some simple code that demonstrates something that cannot (currently) be done in cpython on AppEngine, but is easy with jython on AppEngine: XSLT transforms.
So, without further ado, here is the jython source code for running an XSLT transform on Google AppEngine. It is implemented as a jython WSGI application, using xhaus.com’s modjy WSGI gateway for java servlets that was contributed to the jython project a few months back.
In order to get this code running, I suggest you download the modjy on google appengine demo from our open source site. In that download, there is a jython file called “demo_app.py”. Simply replace the entire contents of that file with the code below, and you’re good to go. If you need help with getting the modjy demo application working on Google AppEngine, see the documentation on the modjy wiki: Running jython WSGI applications on Google AppEngine, with modjy.
__doc__ = """ A demonstration of how to run XSLT transforms on Google AppEngine with jython (not cpython). Please feel free to use this code in whatever way you wish. """ from java.io import StringReader, StringWriter from javax.xml.transform import Transformer, TransformerFactory from javax.xml.transform.stream import StreamResult, StreamSource xml_data = """ <books> <book> <title>2001 - A Space Odyssey</title> <author>Arthur C Clarke</author> </book> <book> <title>I, Robot</title> <author>Isaac Asimov</author> </book> <book> <title>Kil'n people</title> <author>David Brin</author> </book> </books> """ xslt_source = """ <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > <xsl:template match="books"> <html> <head><title>A list of books, transformed into html from xml using xslt and jython.</title></head> <body> <table border="1" width="50%" align="center"> <caption>A list of books, transformed into html from xml using xslt and jython.</caption> <tr><th>Title</th><th>Author</th></tr> <xsl:for-each select="book"> <tr><td><xsl:value-of select="title/text()"/></td><td><xsl:value-of select="author/text()"/></td></tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet> """ def generate_html(xml_data, xslt_source): transformer = TransformerFactory.newInstance().newTransformer(StreamSource(StringReader(xslt_source))) output_buffer = StringWriter() transformer.transform(StreamSource(StringReader(xml_data)), StreamResult(output_buffer)) return output_buffer.buffer.toString() def handler(environ, start_response): result = generate_html(xml_data, xslt_source) start_response("200 Hoopy", [ ('content-type', 'text/html') ]) return [result]