|
If you worked with XSL-T for a while, you must have experienced the
verbosity of the XSL-T syntax. Writing a Java or C style switch statement
easilly sprawls to (from the
XSL-T Recommendation Section 9.2) the code shown on the left
where the code on the right would be just as clear and a lot less
typing. ShoXS is a syntax for representing XSL-T stylesheets in a less
verbose syntax.
<xsl:choose>
<xsl:when test='$level=1'>
<xsl:number format="i"/>
</xsl:when>
<xsl:when test='$level=2'>
<xsl:number format="a"/>
</xsl:when>
<xsl:otherwise>
<xsl:number format="1"/>
</xsl:otherwise>
</xsl:choose>
|
switch {
case ($level=1) {
<xsl:number format="i"/>
}
case($level=2) {
<xsl:number format="a"/>
}
default {
<xsl:number format="1"/>
}
}
|
Example
The example stylesheet from Section
D of the XSL-T spec of 1,127 characters (see below left) is compressed
to a 732 character ShoXS file (below right that) a reduction of 35%. The
xsl2ShoXS stylesheet of 10,095 is compressed to a 5,689 character ShoXS file, a reduction of
44%. In my experience, typically a reduction of around 40% can be achieved.
|
Sample XSL file
|
Sample ShoXS from sample XSL file
|
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform"
xmlns=
"http://www.w3.org/TR/xhtml1/strict"
version="1.0">
<xsl:strip-space
elements="doc chapter section"/>
<xsl:output method="xml" indent="yes"
encoding="iso-8859-1"/>
<xsl:template match="doc">
<html>
<head>
<title>
<xsl:value-of select="title"/>
</title>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="doc/title">
<h1>
<xsl:apply-templates/>
</h1>
</xsl:template>
<xsl:template match="chapter/title">
<h2>
<xsl:apply-templates/>
</h2>
</xsl:template>
<xsl:template match="section/title">
<h3>
<xsl:apply-templates/>
</h3>
</xsl:template>
<xsl:template match="para">
<p>
<xsl:apply-templates/>
</p>
</xsl:template>
<xsl:template match="note">
<p class="note">
<b>NOTE: </b>
<xsl:apply-templates/>
</p>
</xsl:template>
<xsl:template match="emph">
<em>
<xsl:apply-templates/>
</em>
</xsl:template>
</xsl:stylesheet>
|
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform"
xmlns=
"http://www.w3.org/TR/xhtml1/strict"
version="1.0">
<xsl:strip-space
elements="doc chapter section"/>
<xsl:output method="xml" indent="yes"
encoding="iso-8859-1"/>
match(doc){
<html>
<head>
<title>
val(title)
</title>
</head>
<body>
apply()
</body>
</html>
}
match(doc/title){
<h1>
apply()
</h1>
}
match(chapter/title){
<h2>
apply()
</h2>
}
match(section/title){
<h3>
apply()
</h3>
}
match(para){
<p>
apply()
</p>
}
match(note){
<p class="note">
<b>NOTE: </b>
apply()
</p>
}
match(emph){
<em>
apply()
</em>
}
</xsl:stylesheet>
|
ShoXS syntax
In principle, there is a mapping of the xsl-t elements most used
(by me at least) to ShoXS equivalents. The more obsccure xsl-t elements
can be just used as part of a ShoXS file. In fact, any xsl-t element can
be used in a ShoXS file, so every xsl-t file is a ShoXS file as well.
Below, the mapping between the xsl-t elements and its possible ShoXS
syntax is shown.
Short conversion table:
| xsl-t syntax | ShoXS syntax |
| xsl:for-each | for[](@select) {} |
| xsl:if | if[](@test) {} |
| xsl:choose | switch[] {} |
| xsl:when | case[](@test) {} |
| xsl:otherwise | default[] {} |
| xsl:template | fun[mode & priority atts] @name() {} |
| xsl:template | match[mode & priority atts](@match) {} |
| xsl:apply-templates | apply[non-select atts](@select) {} |
| xsl:call-template | call[] @name {} |
| xsl:value-of | val[](@select) |
| xsl:variable | var[] @name="@select"{} |
| xsl:param | par[] @name="@select"{} |
| xsl:with-param | wpar[] @name="@select"{} |
| xsl:attribute | att @name[] = {} |
| xsl:text | text[] "bla" |
| <--bla--> | /*bla*/ OR //bla |
Some notes: every attribute that is not mapped onto specific ShoXS syntax can be
marked up by putting it in between brackets ([]) on the place indicated in the table.
So, the brackets shown above are all optional.
In general, braces ({}) embrace the children of an xsl-element. They are optional
for xsl:for-each, xsl:apply-templates, xsl:param, xsl:with-param and xsl:variable
conversions. They are mandatory for xsl:if, xsl:choose, xsl:when, xsl:otherwise,
and xsl:attribute element conversions.
The elements xsl:param is removed in the xsl2ShoXS
conversion (that is, xsl:params that are not top-level).
Likewise, the xsl:with-param is removed (that is, xsl:with-params
that are not inside apply-templates).
Customizable keywords
ShoXS uses the following standard keywords: for, if, switch, case, default, fun, match,
apply, call, val, var, att and text and the symbols '//' and '/*' and '*/'.
I have playing a bit with making keywords customizable, but have not found
the effort worth the trouble, so it is not available in ShoXSPad.
Comment handling
In ShoXS, there are two ways to insert comments (apart from the standard XML-style
comment of the form <!--comment-->):
1. A C/Java-style comment block, starting with /* and ending in */, potentially spreading
over multiple comments. Nesting of comments is not supported by eShoXS.
2. A C++/Java-style comment starting with // and spreading till the end of the line.
Normally, this works quite well (note that XPath expressions, in which the patters
'//' and '/*' regularly occur do not pose a problem because XPath expressions can
only occur in attributes. Since no comments are allowed inside attribute values,
no ambiguity in translation occurs).
However, if you want to use text containing the sequence '//' or '/*', for example
<xsl:param name='ShoXS-Home'>http://wwww.xm.co.nz</xsl:param>
with its ShoXS equivalent
par ShoXS-Home=''{http://wwww.xm.co.nz}
translates to
<xsl:param name='ShoXS-Home'>http:<!--wwww.xm.co.nz}-->
because the double slash is interpreted as the start of a comment.
Therefore, eShoXS allows you to ignore interpreting // and/or /* as the
beginning of a comment.
Note that because there is no exact way in XML to distinguish the two styles
of comment, toggling from a //-comment to XSL and then back to ShoXS results in
a /*-comment.
String handling
In XSL, attribute values can be either enclosed by double (") or sinlge (') quotes.
In ShoXS, the qoutes are often ommitted for increasing readability. For example,
<xsl:for-each test="XYZ"> is mapped onto
for(XYZ). The string (here XYZ) may contain double or
sinlge quotes, which are treated differently depending on
the enclosing quotes.
Strings in text elements are copied straight into the text element, so
the ShoXS expression text"zap"u" gets translated to <xsl:text>zap"u</xsl:text>
and text'zap"apos;u&2' to <xsl:text>zap"apos;u&2</xsl:text>
Non regular attributes
Since any XSL element can have a namespace attribute, e.g., xsmlns:zap='whatever',
but also 'xml:space' attributes and others,
a provision is required for marking up these attributes in ShoXS. Every ShoXS construct
therefore has a place where these attributes can be added in between brackets.
So, brackets are used for marking up any attribute that is not frequently
used and for which therefore is no specific ShoXS syntax.
See the tools page for details.
Learning ShoXS
Learning ShoXS should not be a big effort. If you know XSL-T but not ShoXS, you can
use ShoXSPad, key in the XSL-T expression and toggle between
XSL-mode and ShoXS-mode (and back). By observing the transformation, it should be
clear pretty quickly what the ShoXS equivalent of XSL is. Since any valid XSL-T is
valid ShoXS as well, you can freely mix XSL-T and ShoXS till you are familiar with
the ShoXS equivalent of the XSL-T expression.
Also, a FAQ is available
and there is the ShoXS Reference Documentation.
|