Variant Stylesheets


The stylesheet just presented is used for the XML specification. The stylesheets used for the XPath and XSLT specifications are slightly different, because these documents use additional element types beyond those used in the XML specification. In each case, the XML source document has an internal DTD subset that supplements the base DTD with some additional element types. For example, the XPath Functions and Operators document uses special tags to mark up function signatures, and the XSLT document has special tags to mark up the proformas used to summarize the syntax of each XSLT element.

In fact, the XSLT 2.0 specification is formatted using a stack of five stylesheet modules, as described in the following sections. The relationship between them is described by the import tree in Figure 10-3.

click to expand
Figure 10-3

diffspec.xsl

This stylesheet module is used to do change marking for the XSLT 2.0 specification. You can see an example of its output at http://www.w3.org/TR /2003/WD-xslt20-20031112/Overview-diff.html .

For historical reasons, change marking is done slightly differently from the way the base XML stylesheet does it: it is derived from the same original code, but has forked. It includes some facilities that aren't in the base specification: for example, the ability to mark each change to say at which internal or external draft each change was introduced, and thus to do change coloring relative to a baseline selected by a stylesheet parameter. For example, a change introduced in draft R might be marked as <phrase diff="add"at="R">new text</phrase> .

The stylesheet module is labeled «version="1.0" » but it actually contains a couple of subtle dependencies on XSLT 2.0, which I will point out as I go along.

The way this stylesheet works is interesting. It contains template rules that override all other rules in the base stylesheet. For example, changes marked as additions ( «@diff="add" » ) are handled by this rule:

  <xsl:template match="*[@diff='chg' and   $show.diff.markup='1' and   (string(@at) &gt; $baseline or not(@at))]"   priority="3">   <xsl:call-template name="diff-markup">   <xsl:with-param name="diff">chg</xsl:with-param>   </xsl:call-template>   </xsl:template>  

This matches every element with the relevant markup, provided that the global parameter $show.diff.markup is enabled.

This is the first place the stylesheet depends on XSLT 2.0. In XSLT 1.0, match patterns in template rules were not allowed to refer to global variables or parameters. This restriction has been lifted in 2.0, and this allows the predicate in the match pattern to refer to two stylesheet parameters, $show.diff.markup and $baseline .

There is also another dependency on XSLT 2.0 in this predicate. Note the condition «string(@at) &gt; $baseline » . With XSLT 2.0, if $baseline is "P" , then the test «string ("R") > "P" » will succeed. With XSLT 1.0, a «> » comparison is always done by converting both operands to numbers . The conversion will produce NaN , and the comparison will be false .

To perform the same test in XSLT 1.0, the simplest solution is probably to write «string-length ( substring-before ($alphabet, @at)) &gt; string-length (substring-before ($alphabet, $baseline)) » , where $alphabet is the string «ABCDE...XYZ » .

Let's look at the named template «diff.markup » to see how this works. The template reads:

  <xsl:template name="diff-markup">   <xsl:param name="diff">off</xsl:param>   <xsl:choose>   <xsl:when test="ancestor::scrap">   <!-- forget it, we can't add stuff inside tables -->   <!-- handled in base stylesheet -->   <xsl:apply-imports/>   </xsl:when>   <xsl:when test="self::gitem or self::bib1">   <!-- forget it, we can't add stuff inside dls; handled below -->   <xsl:apply-imports/>   </xsl:when>   <xsl:when test="ancestor-or-self::phrase">   <span class="diff-{$diff}">   <xsl:apply-imports/>   </span>   </xsl:when>   <xsl:when test="ancestor::p and not(self::p)">   <span class="diff-{$diff}">   <xsl:apply-imports/>   </span>   </xsl:when>   <xsl:when test="ancestor-or-self::affiliation">   <span class="diff-{$diff}">   <xsl:apply-imports/>   </span>   </xsl:when>   <xsl:when test="ancestor-or-self::name">   <span class="diff-{$diff}">   <xsl:apply-imports/>   </span>   </xsl:when>   <xsl:otherwise>   <div class="diff-{$diff}">   <xsl:apply-imports/>   </div>   </xsl:otherwise>   </xsl:choose>   </xsl:template>  

This is pretty pragmatic code, and it almost certainly doesn't handle all possible cases. In effect, it recognizes that the «diff » attribute can occur in three different contexts: contexts where a <span> element can be added to the HTML, contexts where a <div> element can be added to the HTML, and contexts where nothing can be done. In the first two cases, the <div> or <span> element is added, with a «class » attribute that will invoke a CSS rule to cause the text to be displayed with a background color .

But the magic is in the <xsl:apply-imports> instruction, which says that having added a <div> or <span> element, the stylesheet should go on to process the element exactly as it would have done if the diffspec.xsl stylesheet module had not been invoked. The effect of this stylesheet module is thus entirely additive.

The other specifications in the XSLT/XPath/XQuery set use a different technique to produce change markings . For XSLT, the change markup is maintained by hand (and therefore ignores trivial changes considered to be purely editorial). For the other specifications in the family, change markup is generated automatically by a stylesheet that compares two versions of the same document. There is then some manual adjustment of the result to remove obvious flaws, which can easily arise if, for example, two sections are reordered. However, the mechanics of rendering the change markings are essentially the same.

The diffspec.xsl stylesheet used for XSLT imports xslt.xsl , which handles markup specific to the XSLT specification.

This points up a nice little problem: how would one maintain a diffspec.xsl module that could be used as an overlay over a variety of different base stylesheets? To achieve this, the module could not import the underlying module, which means it could not use <xsl:apply-imports> to invoke the overridden template rules. In XSLT 2.0, this can be achieved by exploiting <xsl: next -match>. Instead of diffspec.xsl importing xslt.xsl , the xslt.xsl module could include diffspec.xsl (using <xsl:include> ), relying on the priority of the rules in diffspec.xsl being higher than any rules in xslt.xsl . A call on <xsl:next-match> in diffspec.xsl would then invoke the lower priority rule in xslt.xsl.

xslt.xsl

I developed most of this stylesheet module myself in my role as editor of the XSLT 2.0 specification (some parts were inherited from a similar stylesheet produced by James Clark). It refines the features available from the base stylesheet in three main ways:

  • It handles additional markup that is special to the XSLT specification, for example the proformas used for showing the structure of XSLT instructions, and the markup used for describing error conditions.

  • It refines the presentation used for certain constructs, where the default presentation used in the base stylesheet didn't work well for this document. For example, the number of cross-references to other sections of the specification is so great that using a bold font for these became very distracting for the reader, so they were changed to use a normal font. Clearly, such changes need to be made with great discretion, but this is not the right place to discuss typography or editorial policy issues.

  • It automates certain things that were not automated by the base stylesheets. For example, it provides an automatically generated glossary and indexes of error conditions and outstanding issues; it also automates some of the generation of front material and hyperlinks .

In some cases, these changes have had cascading effects. For example, the fact that some sections of the specification are automatically generated means that the stylesheet (in places) operates in two phases. The issues list is generated as a temporary tree using the markup from the xmlspec vocabulary, and this is then rendered into HTML by applying the standard template rules. Unfortunately, certain things break when this is done, for example the standard <specref> template, shown above on page 674, cannot handle a link from a <specref> element in a temporary tree to a target element in the main source document-the use of the key() function assumes that both source and target are in the same tree. So, the xslt.xsl stylesheet contains a copy of the entire <specref> template rule with one line changed.

This is far from ideal, of course. In such cases, it is better to get the base stylesheet changed, but this always takes time and is not possible when timescales are tight. It can then easily happen that differences between versions of the same template gradually accumulate, and it takes constant vigilance to prevent structural decay. This is not really any different, of course, from any other software endeavor.

The xslt.xsl stylesheet imports two other stylesheet modules, funcproto.xsl and xsl-query.xsl

funcproto.xsl

This stylesheet module does a well-defined job: it formats the function signatures used in the XPath Functions and Operators specification, and also in the XSLT specification. As with the XML production rules, these function signatures use a highly structured form of markup that is completely independent of the final presentation. For example, here is the function signature for the format-date () function:

  <proto class="xslt" name="format-date" return-type="'xs:string"   returnEmptyOk="yes">   <arg name="value" type="xs:date" emptyOk="yes"/>   <arg name="picture" type="xs:string"/>   <arg name="language" type="xs:string" emptyOk="yes"/>   <arg name="calendar" type="xs:string" emptyOk="yes"/>   <arg name="country" type="xs:string" emptyOk="yes"/>   </proto>  

It's worth taking a look at this stylesheet to see how it works (it's available in the downloads for this chapter). There are some interesting features, such as the use of a heuristic calculation that attempts to decide whether to use a single-line format for the function signature, or a multiline format. But I won't include any details here.

xsl-query.xsl

This stylesheet provides a customization of the xmlspec.xsl stylesheet that is used by all the specifications in the XSLT/XPath/XQuery family. It provides facilities to support fine-grained cross-references between the different specifications in this family, and to generate appendices such as error listings and glossaries.

Some of these facilities were introduced first in the XSLT specification, and were then adapted for use in other specifications; in some cases, the XSLT specification has changed to use the common capabilities, in other cases it has not. As with any sizable editorial operation, standards and processes are constantly in flux, and at any given point in time, there will be inconsistencies and overlaps. The fact that these exist in this family of stylesheets should actually be taken as positive evidence that the modular structure of the XSLT language can actually support this kind of change, which can never be synchronized totally across the whole organization. Changes are inevitably piloted in one area, then adopted and adapted in another, and at any one time the overall picture may appear slightly chaotic .




XSLT 2.0 Programmer's Reference
NetBeansв„ў IDE Field Guide: Developing Desktop, Web, Enterprise, and Mobile Applications (2nd Edition)
ISBN: 764569090
EAN: 2147483647
Year: 2003
Pages: 324

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