A transformation expressed in XSLT describes rules for transforming a source tree into a result tree. In constructing the result tree, elements from the source tree can be filtered and reordered, and arbitrary structure can be added.In constructing the result tree, elements from the source tree can be filtered and reordered, and arbitrary structure can be added.
For complete information about XSLT standard see http://www.w3.org/TR/xslt .
Not everything stated in the standard is implemented in the system, and some things work differently. If you want to apply transformations you need two things :
1. Basic structure of the transformation document (TD).
Any tag name, used below, may be optionally preceded by the XSLT namespace: "xsl" prefix. So tag named "template" may be also written as "xsl:template".
This is a description of the syntax of the TD. For details of how the XSLT processor work see below.
1.1. The root.
The root of every TD must be either "transform" or "stylesheet" tag.
1.2. Children of the root.
A transform (stylesheet) contains a set of "template" rules.
1.3. Templates.
A template is instantiated for a particular source element to create part of the result tree. Template rules identify the nodes to which they apply by using a pattern.
Attributes of the "template" tag
"match" attribute
The "match" is a pattern that identifies the source node or nodes to which the rule applies. A pattern specifies a set of conditions (as a XPath expression) on a node. A node that satisfies the conditions matches the pattern; a node that does not satisfy the conditions does not match the pattern.This attribute is required.
"priority" attribute.
The "priority" attribute determines the priority of the rule.
Priorities are used to determine which rule to use if more than one rule matches a given node. If no value is given for this attribute, 0 is substituted. If more than one template still remain, the last defined template is used.
"name" attribute.
The "name" attribute is not implemented.
"mode" attribute
The "mode" attribute contains a string that determines the mode, in which the XSLT processor must be in order to use this rule. The string is completely arbitrary. The default is the empty string. If template does not have a match attribute, it must not have a mode attribute.
Children of the "template" tag.
Anything can be put as child to a template tag, but some tag names have special meaning.
"select" attribute
A select attribute can be used to process nodes selected by an expression instead of processing all children. The value of the select attribute is contains a XPath expression. The expression must evaluate to a node-set. The selected set of nodes is processed in document order, unless a sorting specification is present.
If no value is given, "child::*" is assumed.
"mode" attribute
This attribute sets the XSLT processor in the given mode.
The "apply-template" tag can have optional "sort" children.
This tag apply its content to every node it selects. Its content is similar in every way to the content of a "template" tag and is similarly used, but it may have "sort" tag children that determine the order of processing of the nodes.
Attributes :
The "sort" tag determines the key for sorting of the lists, resulting from XPath expression. When no such tag occurs, the list are processed in document order. Otherwise, they are first sorted. The first sort child determines the first key, the second sort child - the second key and so on.
Sorting is specified by adding sort elements as children of an xsl:apply-templates or for-each element.
"select" attribute
This attribute holds an XPath expression which is evaluated for every node in the list and is then converted either to string or to number. It determines the key value. The default value is ".", which will cause the string-value of the current node to be used as the sort key.
"data-type" attribute
This attribute determines whether the key is converted to string or to number. The default is "string".The following values are allowed:
text specifies that the sort keys should be sorted lexicographically
number specifies that the sort keys should be converted to numbers and then sorted according to the numeric value;
"order"
Order specifies whether the strings should be sorted in ascending or descending order.Valid values are "ascending" and "descending": "ascending" specifies ascending order; "descending" specifies descending order; the default is ascending
The "sort" tags may appear as children of "for-each" and "apply-templates" tags. Elsewhere it is considered as a normal tag without special meaning.
This tag contains a XPath that is evaluated (or casted) to boolean. If the answer is true, then the processor applies the content of the tag to the current node. Otherwise it does nothing.
"test" attribute
The XPath that is evaluated to boolean. It behaves exactly as if the XPath expression was "boolean(original_expression)".
"copy-of" tag
The copy-of element can be used to insert a result tree fragment into the result tree. This element contains a XPath, that is evaluated either to list of nodes, or to boolean, number or string. In the first case each of the selected nodes together with its subtree is attached to the result. In the last cases the XPath is converted to string and is then added to the result tree.(As value-of does)
"select" attribute
Selects the nodes (or data) to be copied.
"copy" tag
This tags copies the current node and its attributes. The subtree is not copied. No attributes are defined for this tag.
"value-of" tag
This element is instantiated to create a text node in the result tree.
"select" attribute
The attribute is required. Selects the nodes (or data) to be converted and copied. This are the special meaning tags. Every other tag or character data is directly copied to the result tree.
2. XSLT processor.
The XSLT processor takes as input a source document (SD) and a transformation document (TD) and returns a new document that is called the result document (RD). Its works as follows :
Finds the template that matches the document element of the SD and has mode "" and highest priority.
Applies that template. In the template there may be "apply-template" tags that run the processor recursively. Every node that has no special meaning is attached to the result tree in the right position node (RP). At first this RP is the document node of the RD itself. For more information see the examples below. As one may see, the resulting document may not have only one root. To avoid this, only the first child of the Document node is actually used. This is not valid when you apply the transformation inside the document rather than to the entire document.
Examples.
The “books” example.
Lets assume that we have a set of "books", and every "book" tag has 0 or more "author" tags. We want to extract all the authors and put them in a new document. The following XSLT document will do the job.
Example :
<books>
<book>
<title> Alice in Wonderland </title>
<author> Louis Carol </author>
</book>
<book>
<title>2001 HPSG-based syntactic TreeBank of Bulgarian (BulTreeBank).</title>
<author> Simov K </author> <author> Popova G </author>
<author> Osenova P </author>
</book>
<book>
<title>Creatures of Light and Darkness</title>
<author> Roger Zelazny </author>
</book>
<book>
<title>The Chronicles of Amber </title>
<author> Roger Zelazny </author>
</book>
</books>
Note :We will use the "//" for comments. They are not part of the TD.
<transform>
<template match="*"> // the only template that matches every tag
<authors> // this tag has no special meaning
<for-each select="child::book/child::author"> // for every author of every book
<sort/> // sort the authors
<copy-of select="."/> // copy its "author"s tags
</for-each> // end cycle
</authors>
</template> // end template
</transform> // end the TD
The result will be:
<authors>
<author> Louis Carol </author>
<author> Osenova P </author>
<author> Popova G </author>
<author> Roger Zelazny </author>
<author> Roger Zelazny </author>
<author> Simov K </author>
</authors>
As one may see, we will have authors that are mentioned more than once in the RD. Lets fix this! The new SD will be the old RD, and the transformation is this :
<transform>
<template match="authors">// match the root
<copy> // copy the root
<apply-templates/> // apply-templates to its children
</copy>
</template>
<template match="author"> // match every author
<if test="(. != following-sibling::author[1])">// check if it’s the same as its next sibling
// note that the authors are sorted.
<copy-of select="."/>
</if>
</template>
</transform>
And the final result is:
<authors>
<author> Louis Carol </author>
<author> Osenova P </author>
<author> Popova G </author>
<author> Roger Zelazny </author>
<author> Simov K </author></authors>