XSLTXT : An alternative XSLT syntax

Alex Moffat


Table of Contents

Why a different syntax?
Basic principles
Using the alternative syntax.
Converting from XSLTXT to XSLT.
Converting from XML to XSLTXT.
Using XSLTXT in place of XSLT via TXTReader.

Why a different syntax?

The XML syntax for XSLT is very easy to parse, as it's XML, relatively easy to read, but tedious to write once you get past the simplest transformations. I find that the semantics of XSLT get swamped by the syntax of XML. For example, the number of characters used for xml markup can be very large compared to the number used for the actual semantics of the transformations. For example, if you want to write a simple template with a name of foo that takes two parameters and generates a statement like SELECT x FROM y you can write the template element below. This uses approximately 122 characters for markup and 22 for meaning.

      
<xsl:template name="foo">
  <xsl:param name="a"/>
  <xsl:param name="b"/>
SELECT <xsl:value-of select="$a"/> FROM <xsl:value-of select="$b"/>
</xsl:template>
    

In contrast the alternative syntax can express this using only 31 characters of markup and 22 characters for meaning, as shown below. I hope that this makes the meaning clearer and it is certainly quicker to write.

      
tpl .name "foo" ("a", "b")
  "SELECT "
  val "$a"
  " FROM "
  val "$b"
    

XSLTXT makes no changes to XSLT semantics. The things that are tedious to do in XSLT are still tedious in XSLTXT but at least there is less typing. The advantage of this approach is that in Java a XMLReader can be constructed that will parse an XSLTXT file and produce SAX events as if an XSLT file was being processed. XSLTXT can therefore be used in place of XSLT without having to build another XSLT processor.

Basic principles

XSLTXT does four things to try to reduce the number of markup characters.

  • Use indentation to delimit the block structure instead of start and end markers.
  • Reduce the length of some of the names used, for example template becomes tpl
  • Required attributes no longer have attribute names, instead they are positional.
  • In some situations param and with-param statements can be written using parentheses.

An XSLTXT stylesheet is made up of statements, modifiers, comments, quoted text, XML elements, and whitespace.

Statements

Statements correspond to the elements in XSLT such as <xsl:apply-templates/>. They often have the same name as the element they represent. In some cases though a shorter name is used to help make it easier to write and read XSLTXT.

Modifiers

Modifiers correspond to the optional attributes of the XSLT elements. They are written with a leading period, and are generally named the same as the attribute they represent. For example, the mode attribute is represented by the .mode modifier. The value of the attribute is written as a quoted string following the modifier. So the XSLT element <xsl:apply-templates select="author/given-name"/> would be represented by the XSLTXT statement apply .select "author/given-name"

Comments

Comments start with a # as the first non whitespace character on a line and proceed to the end of the line.

Quoted text

The value of any modifier or any text to be output must be surrounded by ". This is not the same as XSLT where any text not recognized as an XML element is output.

XML elements

You can include XML elements in the stylesheet just as in XSL. However, you should not write the close element. For example in XSL you might write

            
<first-name>Bob</first-name>
	  

but in XSLTXT you would write

	    
<first-name>
  "Bob"
	  

instead as indentation is used to show the block structure of the element.

Whitespace

is ignored

As with XSLT some XSLTXT statements can contain other statments. XSLTXT uses indentation to mark its block structure in a similar way to Python and Haskell so it does not need the end element markers of XML. A XSLTXT statement includes all those statements whose indentation is greater than it's own indentation. For example in the two templates below

      
tpl .mode "client"
  "Client "
  val "@name"
      
tpl .mode "server"
  "Server "
  val "@host"        
    

It can be seen from the indentation that the first, with .mode "client", contains the string "Client " and the statement val "@name", while the second, with .mode "server" contains the string "Server " and the statement val "@host".

Statements, modifiers and comments in XSLTXT are written without quotes. Everything else is written in quotes.

Required attributes need no modifier, just a value. For example the import element has a required attribute href. In XSLTXT the value for this attribute is placed directly after the statement with no modifier. So, <xsl:import href="others.xsl"/> becomes import "others.txt" If a statement has more than one required attribute they must be entered in the correct order.

Optional attributes are preceeded by their name with a period in front of it, for example the mode attribute of a template statement would be written .mode "myMode"

Parameters, whether expressed in xsl as param or with-param can be represented in XSLTXT in two ways. The representation used depends on how any parameter value is represented. The first representation can be chosen if all of the param or with-param statements either have no value, use the select attribute to provide a value, or if there value is only a text string. This representation surrounds the parameters with ( and ) and separates each parameter name from its value, if it has one, with a :jif the value is a select or a % if the value is to be used as a text value. So,

      
<xsl:template name="bySize">
  <xsl:param name="height" select="@height"/>
  <xsl:param name="weight" select="@weight"/>
  <xsl:value-of select="$height"/> * <xsl:value-of select="$weight"/>    
</xsl:template> 
    

would be shown in XSLTXT as

      
tpl .name "bySize" ("height":"@height", "weight":"@weight")
  val "$height"
  " * "
  val "$weight" 
    

and a call to this template could be written

      
call "bySize" ("height":"@height", "weight"%"100")
    

if the weight was going to be passed as a string with a value of 100. This would be written in xslt as

      
<xsl:call-template name="bySize">
  <xsl:with-param name="height" select="@height"/>
  <xsl:with-param name="weight">
    <xsl:text>100</xsl:text>
  </xsl:with-param>
</xsl:call-template>
    

If a parameter does not have a default value then the : or % is not required. So <xsl:param name="foo"/> would become ("foo")

Handling of import and include statements. During conversion from XSLTXT to XSLT or vise versa the extension on urls being imported or includes is swapped.

Using the alternative syntax.

Converting from XSLTXT to XSLT.

In the directory src/com/zanthan/xsltxt/examples is an example called TXTConverter.java that demonstrates how to convert from XSLTXT to XSL. It has comments to explain what the steps are and should form a good basis if you want to program something similar yourself.

Converting from XML to XSLTXT.

In the directory src/com/zanthan/xsltxt/examples is an example called XSLConverter.java that demonstrates how to convert from XSL to XSLTXT. It has comments to explain what the steps are and should form a good basis if you want to program something similar yourself.

Using XSLTXT in place of XSLT via TXTReader.

In the directory src/com/zanthan/xsltxt/examples is an example called TXTStyler.java. This demonstrates how to use a TXTReaderTwo instance to process an XSLTXT file directly into xsl style sheets.