Send via SMS

Monday, March 27, 2006

XML Macros

http://littlelanguages.com/web/languages/xmlmacros/

There are many complex things which can be done with XSLT, and because of this, many people overlook the very simple things which XSLT can also provide. Previously, I discussed XSLT page compilers, but there is a technique buried in that idea which I thought should get some more light, so I'm presenting it here as it's own thing.

Due to the way that XSLT processing descends, it is possible to use the XSLT identity transform in adition to some simple templates to write XSLT transformations which behave very similarly to hygenic macros (possibly identically, but my Scheme is still weak, so I'm avoiding that statement). You can extend existing XML languages with new elements, and use simple XSLT documents to resolve those elements down to the base language which you are extending.

This often proves to be a powerful technique, especially when designing new languages, as a macro resolving transformation can be performed on your new language before the transformation which provides its semantics, dramatically reducing the implementation complexity. The basic approach resolves arround that old workhorse of XSLT hackers, the identity transform:

<xsl:transform version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<!--
 ! This transform provides a guide towards defining
 ! XML macros using XSLT. We expand only our XML
 ! extensions, and preserve everything else in a
 ! document.
 +-->

<xsl:template match="node()">
  <!--
   ! This is an identity template in XSLT. However,
   ! due to the very low specificity (a technical
   ! aspect of XSLT) of the match, other templates
   ! will override this one when they match.
   +-->
  <xsl:copy>
    <xsl:for-each select="attribute::*">
      <xsl:copy/>
      </xsl:for-each>
    <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

<xsl:template match="bi">
  <!--
   ! This defines the element 'bi',
   ! which is both bold and italic.
   +-->
  <b><i>
    <xsl:apply-templates/>
    </i></b>
  </xsl:template>

<xsl:template match="def">
  <!--
   ! This defines the element 'def',
   ! which provides a link to search the web
   ! for the definition of a term.
   +-->
  <a href="http://google.com/search?q=define%3A{.}">
    <xsl:value-of select='.'/>
    </a>
  </xsl:template>

</xsl:transform>
Which permits us to transform this input document, which isn't quite HTML:
<html>
<head>
  <title>Sample</title>
  </head>
<body>
Here is <bi>my</bi> page,
 and I like <def>monkeys</def>.
  </body>
  </html>
Into this output document, which is pure HTML:
<html>
<head>
<meta http-equiv="Content-Type"
 content="text/html; charset=UTF-8">
  <title>Sample</title>
  </head>
<body>
Here is <b><i>my</i></b> page,
 and I like
 <a href="http://google.com/search?q=define%3Amonkeys">monkeys</a>.
  </body>
  </html>

0 Comments:

Post a Comment

Links to this post:

Create a Link

<< Home