XML Request Transforms (or XSLTpages) is new syntax for building web applications.
XRT is not another framework... it is a new way of describing the resources available in your webapp. You can think of it like an Apache virtual host config file, or a Java(TM) Servlet web.xml file.
About XRT
The idea behind XRT is that by creating a new syntax for describing web applications we can build RESTfull webapps in a very agile way. XRT can allow you to dispatch resource handling based on resource paths but also on other things or combinations of things:
- content language
- content type
- cache selectors
- http parameters
Example
Here's an example XRT document that describes a simple web based bookmark application:
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:http="http://www.tapsellferrier.co.uk/namespace/xslt_http_ns" xmlns:python="http://www.tapsellferrier.co.uk/xslt-dynamic-function-languages/python" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xsl:exclude-result-prefixes="python"> <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" /> <xsl:include href="bookmark-created.xslt"/> <xsl:include href="bookmark-list.xslt"/> <xsl:template match="/"> <xsl:apply-templates select="/http:request"/> </xsl:template> <!-- List all the records --> <xsl:template match="http:request[http:method = 'GET']"> <xsl:variable name="bookmarks" select="python:bookmark.listall()"/> <xsl:apply-templates select="$bookmarks"> <xsl:with-param name="http" select="/http:request"/> </xsl:apply-templates> </xsl:template> <!-- Create new records --> <xsl:template match="http:request[http:method = 'POST']"> <xsl:variable name="toadd" select="//http:parameter[http:name = 'href']/http:value"/> <xsl:variable name="updated" select="python:bookmark.add(string($toadd))"/> <xsl:apply-templates select="$updated" mode="created"> <xsl:with-param name="statuscode">201</xsl:with-param> <xsl:with-param name="toadd" select="$toadd"/> <xsl:with-param name="request" select="/http:request"/> </xsl:apply-templates> </xsl:template> </xsl:stylesheet>
XRT uses the W3C's XSLT language to specify the web application. XSLT is a very powerfull functional language with facilities for talking to code written in imperative languages.
Example imperative code
An example of XRT calling an imperative language can be seen
in the above XRT in the second xsl:template
match. The python method bookmark.listall
is
called. Here's the text of that method:
def listall(): if not os.path.exists(filename): return f = open(filename, "r+") for bookmark in f: yield bookmark f.close() return
XRT takes the output of this method and transforms it into XML and then passes it back to the XSLT script. In this way user's do not need to conform to any particular framework rules.
XRT and Agile development
XRT doesn't need to call imperative languages of course; with XSLT it's trivial to import XML documents. So one very agile way to develop webapps is to:
- sketch out the XML content that your application will produce
- write an XRT to define how requests map to transforms of the XML files into HTML (or SVG or XUL or whatever)
- when you have a working application start replacing the static XML files with code that produces the same XML.
Example include
Note that the above XRT isn't the whole story. You will
notice that the xsl:include
statements which
are there to bring in further XRT. Here's the text of
the bookmark-list.xslt
file:
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="items"> <html> <head> <link rel="stylesheet" href="list.css" type="text/css"/> </head> <body> <h1>Bookmarks</h1> <xsl:choose> <xsl:when test="not(item)"> <div>No bookmarks yet</div> </xsl:when> <xsl:otherwise> <ul> <xsl:for-each select="item"> <li><xsl:value-of select="."/></li> </xsl:for-each> </ul> </xsl:otherwise> </xsl:choose> <form method="POST" action="/"> <fieldset> <label>Title</label><input type="text" name="title" value=""/><br/> <label>Href</label><input type="text" name="href" value=""/><br/> <label>Keyword</label><input type="text" name="keyword" value=""/><br/> <input type="submit" name="add" value="add"/> </fieldset> </form> </body> </html> </xsl:template> </xsl:stylesheet>
This XRT is called when the first XRT applies templates to the python call.
Of course, it's not necessary to use includes, you could put the whole XRT into one file. But that would make it less readable.
Ongoing development
XRT is a work in progress. There are demonstrations that you can play with available in the CVS module.
At the moment you need Apache/mod_python to make XRT work and the only language that can be called is python. I hope to change that by reimplementing XRT in C. At that stage users will be able to call code in any language from XRT.
Can you help?
Yes, you probably can because XRT needs work in a number of areas:
- the current demonstrations of XRT need to be cleaned
up: logos, more styling, more facilities.
If you can write HTML and CSS or produce graphics this is how you could help. - new demonstrations need to be written.
If you can write Python code or XSLT then you should be able to do this. - the new C based version needs to be written.
I am working on this but if you're a C programmer or know much about the internals of libxml2 or libxslt then you can help with this.
If you want to help in anyway you probably need to check out the savannah project where XRT is hosted.