Resin Documentationapp server |
xslt extensible stylesheet language
The extensible stylesheet language is a language for transforming XML documents to new XML documents. It's based on matching elements in the XML tree and replacing the element with new XML. For example, replacing a 'definition' tag with an HTML table with a silver background. XSLT processes the input document recursively from the top down, essentially a depth first traversal of the tree. When it examines each node, it finds the best match from all the templates. XSLT then follows the processing instructions for the matching template, usually adding text to the output. If XSLT cannot find a matching template, it applies default rules. Text gets copied to the output. The children of elements are processed, but the elements themselves are not copied. So a completely blank XSLT stylesheet will remove all the tags and just print out the text. When it's done with the current node, XSLT moves to the next one until the entire input tree is complete. For example, it might process an HTML file in the following order:
Resin's XSLT follows the 1.0 W3C specification. <xsl:template ... > ...Establishes a pattern and replacement text.
Pure XSL processes the contents slightly differently than XTP. XSL expects all tags to be valid XML. XTP is more forgiving. If the tag is not one of those defined by XSL, it will treat the tag as raw text.
In the following example, the template matches any 'box' tag. The contents of the box are placed in a centered table 80% of the current width. This example is legal in XTP because the <td> and <tr> are treated as raw text. The example is illegal in XSL because those tags are missing their close tags. <xsl:template match='box'> <center> <table width='80%'> <tr><td> <xsl:apply-templates/> </td></tr> </table> </center> </xsl:template> <p>Here's a boxed quote,</p> <box> To be or not to be... </box> <p>Here's a boxed quote,</p> <center> <table width='80%'> <tr><td> To be or not to be... </table> </center> <xsl:apply-templates ... > ...Evaluates the children of the current node.
The first example doubles the contents by calling
<xsl:template match='double'> <xsl:apply-templates/> <xsl:apply-templates/> </xsl:template> <double> Some <foo/> text. </double> Some <foo/> text. Some <foo/> text. The The following example writes the 'a' nodes followed by the 'b' nodes and ignores everything else. <xsl:template match='a-b-test'> <xsl:apply-templates select='a'/> <xsl:apply-templates select='b'/> </xsl:template> <a-b-test> Junk Text. <b/> <a> Good text. </a> More Junk. <b> Some B text. </b> <a> More Good text. </a> </a-b-test> <a> Good text. </a> <a> More Good text. </a> <b/> <b> Some B text. <b> <xsl:text> ...Writes the contents to the output.
<xsl:value-of .../>Writes a calculated value output.
<xsl:template match='ct:sum'> <jsp:expression> <xsl:value-of select='@a'> + <xsl:value-of select='@b'> </jsp:expression> </xsl:template> <xsl:for-each ...> ...Loops over child select patterns.
Usually, stylesheets will want to use the full pattern matching capability given by XSL. Sometimes the specific structure is known, like sections in a chapter. When generating a table of contents, it may be easier to scan over the sections.
<xsl:template match='contents'> <ol> <xsl:for-each select='section'> <li><xsl:value-of select='@title'/></li> </xsl:for-each> </ol> </xsl:template> <xsl:if ...> ...Evaluates the containing content if an expression evaluates to true.
<xsl:import .../>Imports a stylesheet.
<xsl:output .../>Control the output printing.
<xsl:element>Creates a new element. The name can be computed using an attribute value template.
<xsl:template match='a'> <xsl:element name='b{@id}'> <c/> </xsl:element> </xsl:template> <b3><c/></b3> <xsl:attribute>Adds an attribute to the element. The name can be computed using an attribute value template.
<xsl:template match='a'> <c> <xsl:attribute name='b{@id}'> <xsl:value-of select='c{@id}'/> </xsl:attribute> </c> </xsl:template> <c b3='c3'/> <xsl:attribute-set>Defines a named attribute set. The attributes in the set are defined by xsl:attribute elements.
<xsl:attribute-set name='font'> <xsl:attribute name='font-size'>12pt</xsl:attribute> <xsl:attribute name='font-weight'>bold</xsl:attribute> </xsl:attribute-set> <xsl:template match='a'> <c xsl:use-attribute-sets='font'/> </xsl:template> <c font-size='12pt' font-weight='bold'/> <xsl:processing-instruction>Creates a new processing instruction.
<xsl:template match='a'> <xsl:processing-instruction name='foo'> <xsl:text>Text for the PI</xsl:text> </xsl:processing-instruction/> </xsl:template> <?foo Text for the PI?> <xsl:comment>Creates a new comment. The contents of the xsl:comment element become the contents of the comment. <xsl:template match='a'> <xsl:comment> <xsl:text>Text for the comment</xsl:text> </xsl:processing-instruction/> </xsl:template> <!--Text for the comment--> <xsl:copy>Copies the current node, but not children or attributes, to the output. To copy an element, a stylesheet must copy the attributes as well. The following example is the identity stylesheet. It copies input to the output including the attributes. <xsl:template match='@*|node()'> <xsl:copy> <xsl:apply-templates select='@*|node()'/> </xsl:copy> </xsl:template> <xsl:copy-of .../>Copies a sub-tree into the output.
<xsl:variable>Assignes an XSL variable. Variables can be retrieved using the XPath variable syntax.
<xsl:variable name='foo' select='1+1'/> <xsl:template match='a'> <xsl:value-of select='$foo'/> </xsl:template> 2 <xsl:call-template>Calls a named template with the current node.
<xsl:param>Declares an XSL parameter.
<xsl:template name='fun'> <xsl:param name='foo' select='15'/> <xsl:value-of select='$foo'/> </xsl:template> <xsl:template match='a'> <xsl:call-template name='foo'> <xsl:with-param name='foo' select='1+2'/> </xsl:call-template> </xsl:template> 3 <xsl:sort>Sorts nodes in xsl:apply-templates or xsl:for-each.
Note case-order and lang attributes are not implemented<xsl:choose ...> ...Implements an if-elsif-else block.
The
<xsl:template match='a'> <xsl:choose> <xsl:when test='@color="red"'> <xsl:text>stop</xsl:text> </xsl:when> <xsl:when test='@color="green"'> <xsl:text>go</xsl:text> </xsl:when> <xsl:otherwise> <xsl:text>yield</xsl:text> </xsl:otherwise> </xsl:choose> </xsl:template> <xtp:expression>expression ...Executes and prints it to the output.Stylesheets can use any JavaScript expression. The following variables are pre-defined in stylesheets.
In addition, the variable gives access to the servlet PageContext with the property.<xsl:template match='welcome-user'> <xsl:text>Welcome back, </xsl:text> <xtp:expression> out.page.session.value.user <xtp:expression> </xsl:template> <xtp:scriptlet> statement_listExecutes the scriptlet.The JavaScript code can be any statement list. The same implicit variables are allowed in scriptlets as in expressions. The following example creates a number of stars: <@# page language='javascript' #> <xsl:template match='ct:stars'> <xtp:scriptlet> for (var i = 0; i < node.attribute.count; i++) out.write('*'); </xtp:scriptlet> </xsl:template> 1 = <ct:stars count='1'/> 9 = <ct:stars count='9'/> 1 = * 9 = ********* <xtp:declaration>Adds declaration code, i.e. code outside of any function. <xtp:declaration> function dist(x1, y1, x2, y2) { return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); } </xtp:declaration> <xtp:directive.page attributes />Sets page directives
|