updated XSLT/XSD patterns for exyus

2007-09-18 @ 22:24#

in my last post i outlined some internal changes to the exyus engine. this is my follow up to that one. here, i cover the gist of the changes i made to clean up support for XSLT/XSD as a way to 'drive' the resource-handling itself.

i wanted to add some flexibility to resource-handling (via XSLT/XSD), but still keep things simple (see an earlier post on this item). that meant adding support for XSLT for both transformations of the incoming request and transformations of the outgoing response. i also needed to be able to use transformations against the URI to make sure i composed a valid document id for GET(item), DELETE, and PUT methods. along with the possibility of using XSD to validate both POST and PUT entities, this meant some serious trundling of control documents. finally, i wanted to be able to re-use control documents if possible. for example, a single args.xsl might be used for simple transformation of the URL for basic resources, etc.

i was concerned that this change would complicate matters. but, as it turns out, it actually *reduced* the number of XSLT/XSD documents i need to fully support the proper HTTP Methods for the resource. for example, for the user resource described in the previous post, i want to allow DELETE, dis-allow POST and allow PUT(create). i also need to validate any entity sent with the PUT. finally, i need to 'dress up' the GET(list) response to clean up the XML returned to the client. that results in the following XSLT and XSD documents for this resource:

-- XSLT to scan the URL for the document id --
<?xml version='1.0' encoding='utf-8' ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method="text" encoding="utf-8" />

	<xsl:param name="uid" />
	
	<xsl:template match="/">
		<xsl:value-of select="$uid"/>
	</xsl:template>

</xsl:stylesheet>

-- XSD to validate PUT entities --
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
	<xs:element name="user">
		<xs:complexType>
			<xs:all>
				<xs:element name="name" type="xs:string" minOccurs="1" maxOccurs ="1"/>
				<xs:element name="email" type="xs:string" minOccurs="1" maxOccurs ="1"/>
			</xs:all>
		</xs:complexType>
	</xs:element>
</xs:schema>

-- XSLT to clean up GET(list) responses --
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method="xml" encoding="utf-8" omit-xml-declaration="no"/>

	<xsl:template match="root">
		<users xml:base="/xcs/users/">
			<xsl:for-each select="item">
				<user href="{.}" id="{position()}">
					<xsl:copy-of select="document(./@dref)/user/*"/>
				</user>
			</xsl:for-each>
		</users>
	</xsl:template>
	
</xsl:stylesheet>

all in all, not that bad. and i think this does a pretty good job of encapsulating the resource definition.

there are still two items the exyus engine is a bit weak on: 1) allowing clients to optionally control MIME types; 2) returning 'link-able' documents. this will have to come with time.

code