XSL Cookbook¶
Extensible Style Sheets are for XML, what Cascading Style Sheets are for HTML. XML content.
The transformation process is the automated process of copying the information from the source XML document, processing it (e.g., running calculations on it, sorting it, filtering it, etc.), writing the processed information into a new document of a particular presentation type (XML, HTML, XHTML, PDF, CHM, etc), and then applying custom rendering to it (format styling).
Background¶
Unlike HTML content, is ambiguous outside of the content of it’s schema (namespace). Therefore, Extensible Style Sheets are written in a language that allows the XML content to be described generically, and redefined (transformed).
If you think of the process of applying style sheets to HTML content as passive, then it makes sense to view the process of applying style sheets to XML content as active. Since you can do so much more with an XML file than simply style it, the name Extensible Style Sheet is misleading.
The terms are confusing¶
XSL used to refer to the programming language used to program Extensible Style Sheets. Now, the term XSLT is used instead. It stands for “Extensible Stylesheet Language Transformation”. “xsl” is the file extension for Extensible Style Sheets, and it is also used as the XSLT namespace.
The term “Transformation” is misleading. The transformation process doesn’t actually transform XML content (it doesn’t alter the source file).
XSL now refers to a family of three languages¶
And they all play a part in the transformation process: XSLT, XSL-FO, and XPath.
XSLT - the language for transforming source XML content.
XPath - the language for navigating source XML content. XSLT uses XPath to define RegEx-like expressions to match parts of the source XML document. XSLT defines one or more transformation templates, for processing matches; each one with a different XPath match definiton.
XSL-FO - the language for formatting output content.
Rendering in a Web Browser¶
After you create an XSL style sheet for a particular XML file, you can put the XML file up on the web, and it will render according to the style sheet if you embed a reference to the style sheet, within the XML file. This is because modern web browsers can process XSL Transforms (just like Saxon).
The XSL Languages¶
XPath¶
You have to know XPath, in order to understand XSLT. XPath is the language used for searching through an XML source document, and finding & copying pieces of information (node sets). XPath uses RegEx-like expressions for extracting data from an XML source.
Selecting Nodes¶
See: http://www.w3schools.com/xpath/xpath_syntax.asp
nodename Selects all nodes with the name “nodename”. / Selects from the root node. // Selects nodes in the document from the current node that match the selection no matter where they are. . Selects the current node. .. Selects the parent of the current node. @ Selects attributes.
bookstore Selects all nodes with the name “bookstore” /bookstore Selects the root element bookstore
Note: If the path starts with a slash ( / ) it always represents an absolute path to an element!
bookstore/book Selects all book elements that are children of bookstore //book Selects all book elements no matter where they are in the document bookstore//book Selects all book elements that are descendant of the bookstore element. //@lang Selects all attributes that are named lang
XPath Predicates¶
Used to find specific nodes.
Predicates always appear inside brackets “[]”.
/bookstore/book[1] Selects the first book element that is the child of the bookstore element. /bookstore/book[last()] Selects the last book element that is the child of the bookstore element
Selecting Unknown Nodes¶
These are the XPath wildcards.
\* Matches any element node. @* Matches any attribute node. node() Matches any node of any kind.
/bookstore/* Selects all the child nodes of the bookstore element. //* Selects all elements in the document. //title[@*] Selects all title elements which have any attribute.
Selecting Several Paths¶
By using the | operator in an XPath expression you can select several paths. You use the | operator to combine XPath expressions.
Note: In XPath, you use the “OR” operator for AND’ing (sort of like bitwise OR’ing is actually AND’ing.).
//book/title | //book/price Selects all the title AND price elements of all book elements. //title | //price Selects all the title AND price elements in the document. /bookstore/book/title | //price Selects all the title elements of the book element of the bookstore element AND all the price elements in the document.
Notes¶
You might get tripped-up by the use of the OR operator. The “Logical OR” operator “|” and the work “or” (as used in Axes definitions (like “parent or self”) are used to include more paths in the selection. OR means “Either case matches”. There really is no use for AND in matching paths!
XPath Axes¶
An XPath Axis specifies the tree-relationship between the selected nodes and the current node.
ancestor Selects all ancestors (parent, grandparent, etc.) of the current node. ancestor-or-self Selects all ancestors (parent, grandparent, etc.) of the current node and the current node itself. attribute Selects all attributes of the current node. child Selects all children of the current node. descendant Selects all descendants (children, grandchildren, etc.) of the current node. descendant-or-self Selects all descendants (children, grandchildren, etc.) of the current node and the current node itself. following Selects everything in the document after the closing tag of the current node. following-sibling Selects all siblings after the current node. namespace Selects all namespace nodes of the current node. parent Selects the parent of the current node. preceding Selects all nodes that appear before the current node in the document, except ancestors, attribute nodes and namespace nodes. preceding-sibling Selects all siblings before the current node self Selects the current node
Location Path Expression¶
A location path can be absolute or relative.
Each step is evaluated against the nodes in the current node-set.
An absolute location path starts with a slash ( / ) and a relative location path does not. In both cases, the location path consists of one or more steps, each separated by a slash:
Absolute¶
/step/step/...
Relative¶
step/step/...
A step consists of¶
- an axis (defines the tree-relationship between the selected nodes and the current node).
- a node-test (identifies a node within an axis).
- zero or more predicates (to further refine the selected node-set).
Location Step Syntax¶
axisname::nodetest[predicate]
Path Expression Example | Description |
---|---|
child::book | Selects all book nodes that are children of the current node. |
attribute::lang | Selects the lang attribute of the current node. |
child::* | Selects all element children of the current node. |
attribute::* | Selects all attributes of the current node. |
child::text() | Selects all text node children of the current node. |
child::node() | Selects all children of the current node. |
descendant::book | Selects all book descendants of the current node. |
ancestor::book | Selects all book ancestors of the current node. |
ancestor-or-self::book | Selects all book ancestors of the current node - and the current as well if it is a book node. |
child::*/child::price | Selects all price grandchildren of the current node. |
XPath Operators¶
An XPath expression returns either a:
- node-set
- string
- Boolean
- number
Symbol | Meaning | Example | Result |
---|---|---|---|
Computes two node-sets | //book | //cd | Returns a node-set with all book and cd elements. | |
Addition | 6 + 4 | 10 | |
Subtraction | 6 - 4 | 2 | |
Multiplication | 6 * 4 | 24 | |
div | Division | 8 div 4 | 2 |
= | Equal | price=9.80 | true if price is 9.80, false if price is 9.90. |
!= | Not equal | price!=9.80 | true if price is 9.90, false if price is 9.80. |
< | Less than | price<9.80 | true if price is 9.00, false if price is 9.80. |
<= | Less than or equal to | price<=9.80 | true if price is 9.00, false if price is 9.90. |
> | Greater than | price>9.80 | true if price is 9.90, false if price is 9.80. |
>= | Greater than or equal to | price>=9.80 | true if price is 9.90, false if price is 9.70. |
or | or | price=9.80 or price=9.70 | true if price is 9.80, false if price is 9.50. |
and | and | price>9.00 and price<9.90 | true if price is 9.80, false if price is 8.50. |
mod | Modulus (division remainder) | 5 mod 2 | 1 |
XSLT¶
XSL is the programming language used for creating XSL style sheets, for:
- creating new documents of various types, based on the content in source XML documents,
- processing the data they contain, and
- applying customizations (not to be confused with format styling).
XSLT is the most important part of XSL. It uses XPath to navigate the XML tree structure (nodes), to find and access the XML content (node sets).
XSLT Stylesheet Elements¶
Element | Description |
---|---|
<xsl:template match=”/”/> | Defines a template to match a node from the input stream (making it the current element). |
<xsl:value-of select=”title”/> | Defines the node to match, and then extracts its value. |
<xsl:for-each select=”catalog/cd”/> | Defines a collection of nodes to match, and then loops through them. |
<xsl:sort select=”artist”/> | Used to sort the output. Meant to be used within the <xsl:for-each/> loop. |
<xsl:if test=”price > 10”/> | Used to refine the match by filtering-out content. |
<xsl:choose/> | Used to refine the match in specific cases (by filtering-out content). |
<xsl:when test=”price > 10”/> | |
<xsl:otherwise/> | |
<xsl:apply-templates/> | Applies a template to the current element or to the current element’s child nodes. |
Include vs. Import¶
Both of these directives bring more templates into the current stylesheet. The difference between them lies in how conflicts are handled - when both stylesheets contain templates that the exact same node.
<xsl:include href=”fixup_href.xsl”/> Use include when you want imported stylesheet’s templates to be used.
<xsl:import href=”common.xsl”/> Use import when you want the current stylesheet’s templates to be used. I.e. imported stylesheets are always overriden. An import element must always be a top-level element, and must always come before any other elements.
XSL Parameters¶
- A template takes a paramter when you declare a parameter, but you don’t initialize it.
- E.g., <xsl:param name=”tableTitle”/>
Modules¶
A module is an XSL file that you intend to include in the main stylesheet.
Each module defines generic XSLT parameters and templates that can be used from different stylesheets.
E.g.,
<xsl:import href=”params.xsl”/> <xsl:import href=”common-code.xsl”/> <xsl:import href=”page-layout.xsl”/>
Use the Validation Scenarios to validate such compound/interconnected XSL stylesheets.
XSLT Devopment Environmentgs¶
Adobe Dreamweaver¶
Drag & drop XML schema elements from the Bindings panel, onto the Design view, not the code view. When you do this, the statement that appears in the code view is properly tagged as <xsl:value-of select=”Bla bla bla”/>
In a repeating region, the expression for the repeated element isn’t the full-qualified name of the element. It is simply the name of the element (its local name).
<xsl:for-each select="project/file/class/property">
<p><xsl:value-of select="name" disable-output-escaping="yes"/></p>
</xsl:for-each>
In oXygen XML Editor¶
Use Master Files as containers to manage housekeeping for things like intellesense (Content Completion Assistant), includes, validation, etc.
These are the XSL files that are not imported or included in other files. The files that included or imported are known as Modules. You can have multiple Master Files in your project, and each Master File can include references to files that are common to other Master Files.
As a rule of thumb, break large XSL files into multiple files, and use one of them to include the others.
Ctrl+Click on a template name in an XPath expression in an XSL file - to find out where it is included elsewhere in the project.
“Component Dependency Helper” - Click the little light bulb that appears in place of the line number.
To search for declarations and references, and to rename components.
When Creating an XSL¶
When you use oXygen to do this, it automatically creates an XSL file that contains all the needed namespace declarations.
When you save the XSL file, set the transformation scenario. All you have to do is select the XML file for the source (the document with the current focus will automatically become the XSL file).
You can creates templates easily by dragging and dropping nodes from the XSLT/Query Input pane!
Debugging Transformations¶
In the XSLT Debugger Perspective, click the blue right-arrow to run the transformation (Run), not the Run to End.
Enable XHTML output.
Then you can double-click parts of the HTML output to see where the part of the XSL file that generated it.
You can also double-click line items in the Output Mapping Stack to highlight the associated line in the XSL file.
Think of the Output Mapping Stack as a trail of breadcrumbs.
To see the transform in process, set breakpoints, and click Run.
This is better than stepping through the code, one line at a time.
Conditional Breakpoints
Open the Breakpoints tab.
You can set breakpoints that evaluate to boolean results.
Scenario-based XSLT Debugging
This allows you to specify which files to use for the input XML
From the Editor perspective, click the Debug Scenario button.
Folding¶
You can add “foldable”, “folded”, and “not-foldable-child” declarations to CSS rules for style selectors.
E.g.,
sect1
{
foldable: true;
not-foldable-child: figure;
}
figure
{
foldable: true;
folded: true;
not-foldable-child: title;
}
Questions?¶
When is it appropriate to use ‘for-each’ loops, as opposed to exploiting the inherent recursive behavior of templates?
When should you use template ‘names=’, as opposed to using ‘match=’?