Section 4.5.  Overview of an XSLT stylesheet

  
Prev don't be afraid of buying books Next

4.5 Overview of an XSLT stylesheet

This section attempts to describe and classify the main building blocks of a web site XSLT stylesheet. You may find it useful for exploring this book's stylesheet examples as well as for programming your own transformations.

4.5.1 Templates

The basic idea of XSLT is this: Run into a context, invoke the corresponding template. Templates usually constitute the bulk of a stylesheet's code. But are all templates created equal? There are several meaningful distinctions that you should keep in mind when building your template library.

  • Applicable vs. callable templates. Most regular templates are of the applicable kind. Such a template has a match attribute and is activated automatically whenever the source context matches. You can also use an xsl:apply-templates instruction (hence the term applicable [14] ) to specify a nodeset to feed through the built-in template-matching mechanism of XSLT.

    [14] The XSLT specification calls applicable templates template rules because the match attribute is effectively a rule that governs when to apply the template. I'm trying to avoid the official term because applicable template seems to better describe a unit consisting of both the template itself and its applicability rule.



    Callable templates, on the other hand, do not necessarily have a match , but they have a name attribute. To run such a named template, you use an xsl:call-template instruction (hence the term callable [15] ) supplying the template name and, optionally , parameters.

    [15] The XSLT specification uses the term named templates . Again, I consider the fact that a template can be called to be more important than the fact that it has a name.

    Formally, the dividing line between applicable and callable templates is rather blurry; you can use xsl:call-template to run an applicable template with match (if it also has a name ), and both xsl:call-template and xsl:apply-templates can supply parameters to the templates they pass control to.

    But architecturally, this is an important distinction. Use callable templates for chunks of code that you want to share between applicable templates. Moreover, use them for any sizable chunk of code that is sufficiently context-independent and represents a separate uniteven if it's only used once. Removing such independent units into aptly named callables will make your stylesheet more readable and easier to maintain.

    One thing you should remember is that a callable template (even of the called-only-once kind) must really be context-independent. It cannot rely on the source context because it might be called from different contexts, but it may depend on parameterswhich can therefore be used to add variability to the output of a callable template.

  • Push vs. pull templates. The natural XSLT programming style whereby you let templates take care of their own execution is often called the push style. What you do with this approach is push your source into the stylesheet and let its many templates tear it into many pieces for processing. Push-oriented templates are relatively small and independent, with few, if any, control flow instructions.

    The opposite is of course the pull style, which is more like the approach of traditional programming languages. Here, you explicitly program your templates to pull information from the source by using XPath expressions and control flow code (such as for-each loops or conditional instructions). Pull-oriented templates are therefore bigger; they usually match top-level elements (like page or block ) and are heavily linked to other templates by means of explicit xsl:call-template or xsl:apply-templates calls.

  • Trunk vs. branch templates. The trunk and branches referred to in this distinction are, of course, those of the source document tree. Trunk templates are either callable, or they match absolute paths (e.g., / or /page ) that are known to occur a fixed number of times in fixed contexts. Branch templates, conversely, handle "hanging" contexts (such as p or @id ) that may occur almost anywhere .

    The other distinctions we've talked about naturally parallel this one and are best understood in conjunction with it. Indeed, trunk templates more often pull than are pushed against. Their goal is to build the high-level structure of the HTML page, and this structure is usually quite different from the source structure. We cannot therefore sit and wait for the necessary bits to come our way; we must take control and pull what we need from the source. For the same reason, many trunk templates are callable rather than applicable; in some cases, only the root template (matching /) is applicable, and all other trunk templates are called from it.

    This approach, however, only works down to a certain level. As we descend, [16] the source tree becomes wider and more varied. At some point, the pull style no longer works; we cannot foresee all possible combinations of elements that may happen at the lower levels of the source tree. This is where we switch to the branch templates that, conversely, are mostly push-oriented and applicable.

    [16] In computer science, trees grow downward, so you have to descend in order to go from a tree's trunk to its branches.

    In terms of psychology, trunk templates are conscious plans, while branch templates are knee-jerk reactions . Both are necessary for survival.

4.5.2 Layout code

That's the ancient curse of HTML ... tables, transparent spacer images, height and width specifications, and tables again. CSS has alleviated the pain a lot, but you still have to fiddle with tables quite often, especially with complex multicolumn layouts. HTML design is beyond the topic of this book, so in the stylesheet examples, I'll skip or simplify most of this stuff; usually only comments will indicate the position and role of the main chunks of layout code.

It's not all static, of course; layout code may use XPath expressions for retrieving and/or calculating various values, such as width of a column that might depend on the number of items in it. Also, you may need to build, at transformation time, various paths or URIs used in HTML codefor example,


 <img src=  "{$out-img}  empty.gif" width="1" height="30" alt=""/> 


4.5.3 Variables and functions

In XSLT, global variables are created by xsl:variable children of the xsl:stylesheet . For the value of a variable, you can put arbitrary XSLT code or literal result elements inside xsl:variable . Any kinds of values, including tree fragments , nodesets, and sequences, are valid for an XSLT variable (unless you limit its data type with an as attribute).

Don't force users to edit the stylesheet. In a web site transformation stylesheet, it may not even be a good idea to actually store values in stylesheet variables. Many values such as URIs, paths, text strings, and menu trees are best stored in the master document ( 2.1.2.1 ); use xsl:variable s to extract and prepare this data for the current stylesheet run. Only true constants that will never conceivably change during the lifetime of your web site can be stored right in the stylesheet.

Lazy evaluation. With a functional language such as XSLT, the only result of a variable declaration is that the variable now exists; no side effects are possible or allowed. This allows the XSLT processor to optimize stylesheet execution by declaring the variable only whenand ifnecessary. This feature is called lazy evaluation , but not all XSLT processors behave that way; one of the "lazy" processors is Saxon.

Lazy evaluation means that if, for example, your xsl:variable declaration contains a debugging output ( xsl:message ) or a document creation instruction ( xsl:result-document ), neither will ever get control if its parent variable is not used. And the variable may remain unused simply because none of the templates that reference it are triggered by the current source document. [17]

[17] In fact, about the only code that is guaranteed to run in a stylesheet is an xsl:template match="/" and whatever callable templates, variables, or functions it unconditionally uses.

Functions vs. templates. XSLT functions, introduced in 2.0, are similar to those in other programming languages in that they take zero or more arguments and return a value. However, the really nice thing about XSLT functions is that they can take and return not just atomic values, but sequences and nodesets too. In fact, the only essential difference between a callable template and a function is that callable templates by default attach their output to the result tree, while the output of a function is returned to whoever called it and can be used as a value in an XPath expression.

4.5.4 Control flow

In the push style, XSLT rarely needs any loops, conditional instructions, or function calls. The code inside push-oriented templates is usually linear, and the order of triggering these templates depends only on the structure of the source document. However, as we've just seen, pull-style XSLT occupies the top levels of template hierarchy, and this is where explicit passing of control is quite common.

The inventory of control flow instructions in XSLT is adequate for typical pull processing scenarios; moreover, some of these instructions have parallels in XPath. Thus, calling or applying templates (in XSLT) is similar to calling functions (in XPath). Often, you will use loops ( xsl:for-each in XSLT, for in XPath 2.0) and conditionals ( xsl:if , xsl:choose in XSLT, if in XPath 2.0). On the other hand, the idea of a "goto" statement is apparently so far below and behind XSLT's level of abstraction that no XSLT tutorials I've seen even mention its nonexistence.

4.5.5 Debugging and documentation

Some of the debugging tools unique to Saxon were mentioned in 4.4.2.1 . Other than that, your debugging toolset is pretty much limited to issuing xsl:messages containing xsl:value-of s to check the values of variables or expressions during execution. Do not underestimate this tool; it is perfectly suitable for anything except the most complex debugging tasks . Some software that may help you debug your stylesheets is reviewed in Chapter 6 ( 6.4 ).

As for documentation, XSLT allows you to use elements from arbitrary namespaces at the top level of the stylesheet. This means you can provide structured documentation by interspersing elements from an appropriate vocabulary (such as DocBook or HTML) with your templates, variables, functions, and so on. Since your stylesheet is a valid XML document that can be fed to another stylesheet, various "literate programming" techniques become possible, such as automatic annotation, extracting documentation, and indexing.

Unfortunately, this only works at the top level directly under xsl:stylesheet ; in deeper contexts, foreign namespace elements are treated as literal result elements. This means that the only way to document the innards of a function or template is by using <!-- XML comments --> .

 
  
Amazon


XSLT 2.0 Web Development
ASP.Net 2.0 Cookbook (Cookbooks (OReilly))
ISBN: 0596100647
EAN: 2147483647
Year: 2006
Pages: 90

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net