diff options
author | wisberg <wisberg> | 2002-12-16 17:19:22 +0000 |
---|---|---|
committer | wisberg <wisberg> | 2002-12-16 17:19:22 +0000 |
commit | 3ce247199704eae6b2c92c6e38c69584e3250c52 (patch) | |
tree | cb60b8f3d3f12e666efeb96913a56d2216a28d44 /lib/docbook/docbook-xsl/doc/ch01s03.html | |
parent | c3300283ecc397d26ad9dfe31d1710ec45db2af0 (diff) | |
download | aspectj-3ce247199704eae6b2c92c6e38c69584e3250c52.tar.gz aspectj-3ce247199704eae6b2c92c6e38c69584e3250c52.zip |
initial version
Diffstat (limited to 'lib/docbook/docbook-xsl/doc/ch01s03.html')
-rw-r--r-- | lib/docbook/docbook-xsl/doc/ch01s03.html | 422 |
1 files changed, 422 insertions, 0 deletions
diff --git a/lib/docbook/docbook-xsl/doc/ch01s03.html b/lib/docbook/docbook-xsl/doc/ch01s03.html new file mode 100644 index 000000000..fe30d5ad2 --- /dev/null +++ b/lib/docbook/docbook-xsl/doc/ch01s03.html @@ -0,0 +1,422 @@ +<html><head> + <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> + <title>XSL processing model</title><link rel="stylesheet" href="reference.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V2"><link rel="home" href="index.html" title="DocBook XSL Stylesheet Documentation"><link rel="up" href="publishing.html" title="Chapter 1. DocBook XSL"><link rel="previous" href="ch01s02.html" title="A brief introduction to XSL"><link rel="next" href="ch01s04.html" title="Customizing DocBook XSL stylesheets"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">XSL processing model</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch01s02.html">Prev</a> </td><th width="60%" align="center">Chapter 1. DocBook XSL</th><td width="20%" align="right"> <a accesskey="n" href="ch01s04.html">Next</a></td></tr></table><hr></div><div class="sect1"><a name="d0e195"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="d0e195"></a>XSL processing model</h2></div></div><p>XSL is a template language, not a procedural +language. That means a stylesheet specifies a sample of the +output, not a sequence of programming steps to generate it. +A stylesheet consists of a mixture of output samples with +instructions of what to put in each sample. Each bit of +output sample and instructions is called +a <span class="emphasis"><i>template</i></span>.</p><p>In general, you write a template for each element +type in your document. That lets you concentrate on +handling just one element at a time, and keeps a stylesheet +modular. The power of XSL comes from processing the +templates recursively. That is, each template handles the +processing of its own element, and then calls other +templates to process its children, and so on. Since an XML +document is always a single root element at the top level +that contains all of the nested descendent elements, the +XSL templates also start at the top and work their way down +through the hierarchy of elements.</p><p>Take the +DocBook <tt><para></tt> paragraph element as +an example. To convert this to HTML, you want to wrap the +paragraph content with the HTML +tags <tt><p></tt> and <tt></p></tt>. +But a DocBook <tt><para></tt> can contain +any number of in-line DocBook elements marking up the text. +Fortunately, you can let other templates take care of those +elements, so your XSL template +for <tt><para></tt> can be quite +simple:</p><pre class="programlisting"><xsl:template match="para"> + <p> + <xsl:apply-templates/> + </p> +</xsl:template> +</pre><p>The <tt><xsl:template></tt> element +starts a new template, and +its <tt>match</tt> attribute indicates where to +apply the template, in this case to +any <tt><para></tt> elements. The template +says to output a literal <tt><p></tt> string +and then execute +the <tt><xsl:apply-templates/></tt> instruction. +This tells the XSL processor to look among all the +templates in the stylesheet for any that should be applied +to the content of the paragraph. If each template in the +stylesheet includes +an <tt><xsl:apply-templates/></tt> instruction, +then all descendents will eventually be processed. When it +is through recursively applying templates to the paragraph +content, it outputs the <tt></p></tt> closing +tag.</p><div class="sect2"><a name="d0e247"></a><div class="titlepage"><div><h3 class="title"><a name="d0e247"></a>Context is important</h3></div></div><p>Since you aren't writing a linear procedure to +process your document, the context of where and how to +apply each modular template is important. +The <tt>match</tt> attribute +of <tt><xsl:template></tt> provides that +context for most templates. There is an entire expression +language, XPath, for identifying what parts of your +document should be handled by each template. The simplest +context is just an element name, as in the example above. +But you can also specify elements as children of other +elements, elements with certain attribute values, the first +or last elements in a sequence, and so on. Here is how the +DocBook <tt><formalpara></tt> element is +handled:</p><pre class="programlisting"><xsl:template match="formalpara"> + <p> + <xsl:apply-templates/> + </p> +</xsl:template> + +<xsl:template match="formalpara/title"> + <b><xsl:apply-templates/></b> + <xsl:text> </xsl:text> +</xsl:template> + +<xsl:template match="formalpara/para"> + <xsl:apply-templates/> +</xsl:template> +</pre><p>There are three templates defined, one for +the <tt><formalpara></tt> element itself, + and one for each of its children elements. The <tt>match</tt> attribute +value <tt>formalpara/title</tt> in the second +template is an XPath expression indicating +a <tt><title></tt> element that is an +immediate child of +a <tt><formalpara></tt> element. This +distinguishes such titles from +other <tt><title></tt> elements used in +DocBook. XPath expressions are the key to controlling how +your templates are applied.</p><p>In general, the XSL processor has internal rules that +apply templates that are more specific before templates +that are less specific. That lets you control the details, +but also provides a fallback mechanism to a less specific +template when you don't supply the full context for every +combination of elements. This feature is illustrated by the +third template, for <tt>formalpara/para</tt>. By +including this template, the stylesheet processes a <tt><para></tt> within <tt><formalpara></tt> in +a special way, in this case by not outputting the HTML <tt><p></tt> tags already output by its parent. If this template had not been included, then the processor would have fallen back to the template +specified by <tt>match="para"</tt> described +above, which would have output a second set of <tt><p></tt> tags.</p><p>You can also control template context with +XSL <span class="emphasis"><i>modes</i></span>, which are used extensively +in the DocBook stylesheets. Modes let you process the same +input more than once in different ways. +A <tt>mode</tt> attribute in +an <tt><xsl:template></tt> definition adds a +specific mode name to that template. When the same mode +name is used +in <tt><xsl:apply-templates/></tt>, it acts +as a filter to narrow the selection of templates to only +those selected by +the <tt>match</tt> expression <span class="emphasis"><i>and</i></span> that +have that mode name. This lets you define two different +templates for the same element match that are applied under +different contexts. For example, there are two templates +defined for +DocBook <tt><listitem></tt> elements:</p><pre class="programlisting"><xsl:template match="listitem"> + <li><xsl:apply-templates/></li> +</xsl:template> + +<xsl:template match="listitem" mode="xref"> + <xsl:number format="1"/> +</xsl:template> +</pre><p>The first template is for the normal list item +context where you want to output the +HTML <tt><li></tt> tags. The second template +is called with <tt><xsl:apply-templates +select="$target" mode="xref"/></tt> in the context +of processing <tt><xref></tt> elements. In +this case the <tt>select</tt> attribute locates +the ID of the specific list item and +the <tt>mode</tt> attribute selects the second +template, whose effect is to output its item number when it +is in an ordered list. Because there are many such special +needs when +processing <tt><xref></tt> elements, it is +convenient to define a mode name <tt>xref</tt> to +handle them all. Keep in mind that mode settings +do <span class="emphasis"><i>not</i></span> automatically get passed down to +other templates +through <tt><xsl:apply-templates/></tt>.</p></div><div class="sect2"><a name="d0e357"></a><div class="titlepage"><div><h3 class="title"><a name="d0e357"></a>Programming features</h3></div></div><p>Although XSL is template-driven, it also has some +features of traditional programming languages. Here are +some examples from the DocBook stylesheets. </p><pre class="programlisting">Assign a value to a variable: +<xsl:variable name="refelem" select="name($target)"/> + +If statement: +<xsl:if test="$show.comments"> + <i><xsl:call-template name="inline.charseq"/></i> +</xsl:if> + +Case statement: +<xsl:choose> + <xsl:when test="@columns"> + <xsl:value-of select="@columns"/> + </xsl:when> + <xsl:otherwise>1</xsl:otherwise> +</xsl:choose> + +Call a template by name like a subroutine, passing parameter values and accepting a return value: +<xsl:call-template name="xref.xreflabel"> + <xsl:with-param name="target" select="$target"/> +</xsl:call-template> +</pre><p>However, you can't always use these constructs as you +do in other programming languages. Variables in particular +have very different behavior.</p><div class="sect3"><a name="d0e377"></a><div class="titlepage"><div><h4 class="title"><a name="d0e377"></a>Using variables and parameters</h4></div></div><p>XSL provides two elements that let you assign a value +to a +name: <tt><xsl:variable></tt> and <tt><xsl:param></tt>. +These share the same name space and syntax for assigning +names and values. Both can be referred to using +the <tt>$name</tt> syntax. The main difference +between these two elements is that a param's value acts as +a default value that can be overridden when a template is +called using +a <tt><xsl:with-param></tt> element as in the +last example above.</p><p>Here are two examples from DocBook:</p><pre class="programlisting"><xsl:param name="cols">1</xsl:param> +<xsl:variable name="segnum" select="position()"/> +</pre><p>In both elements, the name of the parameter or +variable is specified with +the <tt>name</tt> attribute. So the name of +the <tt>param</tt> here +is <tt>cols</tt> and the name of +the <tt>variable</tt> is <tt>segnum</tt>. +The value of either can be supplied in two ways. The value +of the first example is the text node "1" and is supplied +as the content of the element. The value of the second +example is supplied as the result of the expression in +its <tt>select</tt> attribute, and the element +itself has no content.</p><p>The feature of XSL variables that is odd to new users +is that once you assign a value to a variable, you cannot +assign a new value within the same scope. Doing so will +generate an error. So variables are not used as dynamic +storage bins they way they are in other languages. They +hold a fixed value within their scope of application, and +then disappear when the scope is exited. This feature is a +result of the design of XSL, which is template-driven and +not procedural. This means there is no definite order of +processing, so you can't rely on the values of changing +variables. To use variables in XSL, you need to understand +how their scope is defined.</p><p>Variables defined outside of all templates are +considered global variables, and they are readable within +all templates. The value of a global variable is fixed, and +its global value can't be altered from within any template. +However, a template can create a local variable of the same +name and give it a different value. That local value +remains in effect only within the scope of the local +variable.</p><p>Variables defined within a template remain in effect +only within their permitted scope, which is defined as all +following siblings and their descendants. To understand +such a scope, you have to remember that XSL instructions +are true XML elements that are embedded in an XML family +hierarchy of XSL elements, often referred to as parents, +children, siblings, ancestors and descendants. Taking the +family analogy a step further, think of a variable +assignment as a piece of advice that you are allowed to +give to certain family members. You can give your advice +only to your younger siblings (those that follow you) and +their descendents. Your older siblings won't listen, +neither will your parents or any of your ancestors. To +stretch the analogy a bit, it is an error to try to give +different advice under the same name to the same group of +listeners (in other words, to redefine the variable). Keep +in mind that this family is not the elements of your +document, but just the XSL instructions in your stylesheet. +To help you keep track of such scopes in hand-written +stylesheets, it helps to indent nested XSL elements. Here +is an edited snippet from the DocBook stylesheet +file <tt>pi.xsl</tt> that illustrates different +scopes for two variables:</p><pre class="programlisting"> + 1 <xsl:template name="dbhtml-attribute"> + 2 ... + 3 <xsl:choose> + 4 <xsl:when test="$count>count($pis)"> + 5 <!-- not found --> + 6 </xsl:when> + 7 <xsl:otherwise> + 8 <xsl:variable name="pi"> + 9 <xsl:value-of select="$pis[$count]"/> +10 </xsl:variable> +11 <xsl:choose> +12 <xsl:when test="contains($pi,concat($attribute, '='))"> +13 <xsl:variable name="rest" select="substring-after($pi,concat($attribute,'='))"/> +14 <xsl:variable name="quote" select="substring($rest,1,1)"/> +15 <xsl:value-of select="substring-before(substring($rest,2),$quote)"/> +16 </xsl:when> +17 <xsl:otherwise> +18 ... +19 </xsl:otherwise> +20 </xsl:choose> +21 </xsl:otherwise> +22 </xsl:choose> +23 </xsl:template> + +</pre><p>The scope of the variable <tt>pi</tt> begins +on line 8 where it is defined in this template, and ends on +line 20 when its last sibling ends.<sup>[<a name="d0e434" href="#ftn.d0e434">1</a>]</sup> The scope of the +variable <tt>rest</tt> begins on line 13 and ends +on line 15. Fortunately, line 15 outputs an expression +using the value before it goes out of scope.</p><p>What happens when +an <tt><xsl:apply-templates/></tt> element +is used within the scope of a local variable? Do the +templates that are applied to the document children get the +variable? The answer is no. The templates that are applied +are not actually within the scope of the variable. They +exist elsewhere in the stylesheet and are not following +siblings or their descendants. </p><p>To pass a value to another template, you pass a +parameter using +the <tt><xsl:with-param></tt> element. This +parameter passing is usually done with calls to a specific +named template +using <tt><xsl:call-template></tt>, although +it works +with <tt><xsl:apply-templates></tt> too. +That's because the called template must be expecting the +parameter by defining it using +a <tt><xsl:param></tt> element with the same +parameter name. Any passed parameters whose names are not +defined in the called template are ignored.</p><p>Here is an example of parameter passing +from <tt>docbook.xsl</tt>:</p><pre class="programlisting"><xsl:call-template name="head.content"> + <xsl:with-param name="node" select="$doc"/> +</xsl:call-template> +</pre><p>Here a template +named <tt>head.content</tt> is being called and +passed a parameter named <tt>node</tt> whose +content is the value of the <tt>$doc</tt> variable +in the current context. The top of that template looks like +this:</p><pre class="programlisting"><xsl:template name="head.content"> + <xsl:param name="node" select="."/> +</pre><p>The template is expecting the parameter because it +has a <tt><xsl:param></tt> defined with the +same name. The value in this definition is the default +value. This would be the parameter value used in the +template if the template was called without passing that +parameter.</p></div></div><div class="sect2"><a name="d0e488"></a><div class="titlepage"><div><h3 class="title"><a name="d0e488"></a>Generating HTML output.</h3></div></div><p>You generate HTML from your DocBook XML files by +applying the HTML version of the stylesheets. This is done +by using the HTML driver +file <tt>docbook/html/docbook.xsl</tt> as your +stylesheet. That is the master stylesheet file that +uses <tt><xsl:include></tt> to pull in the +component files it needs to assemble a complete stylesheet +for producing HTML. </p><p>The way the DocBook stylesheet generates HTML is to +apply templates that output a mix of text content and HTML +elements. Starting at the top level in the main +file <tt>docbook.xsl</tt>:</p><pre class="programlisting"><xsl:template match="/"> + <xsl:variable name="doc" select="*[1]"/> + <html> + <head> + <xsl:call-template name="head.content"> + <xsl:with-param name="node" select="$doc"/> + </xsl:call-template> + </head> + <body> + <xsl:apply-templates/> + </body> + </html> +</xsl:template> +</pre><p>This template matches the root element of your input +document, and starts the process of recursively applying +templates. It first defines a variable +named <tt>doc</tt> and then outputs two literal +HTML elements <tt><html></tt> and <tt><head></tt>. +Then it calls a named +template <tt>head.content</tt> to process the +content of the HTML <tt><head></tt>, closes +the <tt><head></tt> and starts +the <tt><body></tt>. There it +uses <tt><xsl:apply-templates/></tt> to +recursively process the entire input document. Then it just +closes out the HTML file.</p><p>Simple HTML elements can generated as literal +elements as shown here. But if the HTML being output +depends on the context, you need something more powerful to +select the element name and possibly add attributes and +their values. Here is a fragment +from <tt>sections.xsl</tt> that shows how a +heading tag is generated using +the <tt><xsl:element></tt> and <tt><xsl:attribute></tt> elements:</p><pre class="programlisting"> + 1 <xsl:element name="h{$level}"> + 2 <xsl:attribute name="class">title</xsl:attribute> + 3 <xsl:if test="$level<3"> + 4 <xsl:attribute name="style">clear: all</xsl:attribute> + 5 </xsl:if> + 6 <a> + 7 <xsl:attribute name="name"> + 8 <xsl:call-template name="object.id"/> + 9 </xsl:attribute> +10 <b><xsl:copy-of select="$title"/></b> +11 </a> +12 </xsl:element> +</pre><p>This whole example is generating a single HTML +heading element. Line 1 begins the HTML element definition +by identifying the name of the element. In this case, the +name is an expression that includes the +variable <tt>$level</tt> passed as a parameter to +this template. Thus a single template can +generate <tt><h1></tt>, <tt><h2></tt>, +etc. depending on the context in which it is called. Line 2 +defines a <tt>class="title"</tt> attribute that is +added to this element. Lines 3 to 5 add +a <tt>style="clear all"</tt> attribute, but only +if the heading level is less than 3. Line 6 opens +an <tt><a></tt> anchor element. Although this +looks like a literal output string, it is actually modified +by lines 7 to 9 that insert +the <tt>name</tt> attribute into +the <tt><a></tt> element. This illustrates +that XSL is managing output elements as active element +nodes, not just text strings. Line 10 outputs the text of +the heading title, also passed as a parameter to the +template, enclosed in HTML boldface tags. Line 11 closes +the anchor tag with the +literal <tt></a></tt> syntax, while line 12 +closes the heading tag by closing the element definition. +Since the actual element name is a variable, it couldn't +use the literal syntax.</p><p>As you follow the sequence of nested templates +processing elements, you might be wondering how the +ordinary text of your input document gets to the output. In +the file <tt>docbook.xsl</tt> you will find +this template that handles any text not processed by any +other template:</p><pre class="programlisting"><xsl:template match="text()"> + <xsl:value-of select="."/> +</xsl:template> +</pre><p>This template's body consists of the "value" of the text node, +which is just its text. In general, all XSL processors have +some built-in templates to handle any content for which +your stylesheet doesn't supply a matching template. This +template serves the same function but appears explicitly in +the stylesheet.</p></div><div class="sect2"><a name="d0e583"></a><div class="titlepage"><div><h3 class="title"><a name="d0e583"></a>Generating formatting objects.</h3></div></div><p>You generate formatting objects from your DocBook XML +files by applying the fo version of the stylesheets. This +is done by using the fo driver +file <tt>docbook/fo/docbook.xsl</tt> as your +stylesheet. That is the master stylesheet file that +uses <tt><xsl:include></tt> to pull in the +component files it needs to assemble a complete stylesheet +for producing formatting objects. Generating a formatting +objects file is only half the process of producing typeset +output. You also need a formatting object processor such as +the Apache XML Project's FOP as described in an earlier +section.</p><p>The DocBook fo stylesheet works in a similar manner +to the HTML stylesheet. Instead of outputting HTML tags, it +outputs text marked up +with <tt><fo:<i><tt>something</tt></i>></tt> tags. +For example, to indicate that some text should be kept +in-line and typeset with a monospace font, it might look +like this:</p><pre class="programlisting"><fo:inline-sequence font-family="monospace">/usr/man</fo:inline-sequence></pre><p>The templates +in <tt>docbook/fo/inline.xsl</tt> that produce +this output for a +DocBook <tt><filename></tt> element look +like this:</p><pre class="programlisting"><xsl:template match="filename"> + <xsl:call-template name="inline.monoseq"/> +</xsl:template> + +<xsl:template name="inline.monoseq"> + <xsl:param name="content"> + <xsl:apply-templates/> + </xsl:param> + <fo:inline-sequence font-family="monospace"> + <xsl:copy-of select="$content"/> + </fo:inline-sequence> +</xsl:template> +</pre><p>There are dozens of fo tags and attributes specified +in the XSL standard. It is beyond the scope of this +document to cover how all of them are used in the DocBook +stylesheets. Fortunately, this is only an intermediate +format that you probably won't have to deal with very much +directly unless you are writing your own +stylesheets.</p></div><div class="footnotes"><br><hr width="100" align="left"><div class="footnote"><p><sup>[<a name="ftn.d0e434" href="#d0e434">1</a>] </sup>Technically, the scope extends to the end tag of the parent of the <tt><xsl:variable></tt> element. That is effectively the last sibling.</p></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch01s02.html">Prev</a> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right"> <a accesskey="n" href="ch01s04.html">Next</a></td></tr><tr><td width="40%" align="left">A brief introduction to XSL </td><td width="20%" align="center"><a accesskey="u" href="publishing.html">Up</a></td><td width="40%" align="right"> Customizing DocBook XSL stylesheets</td></tr></table></div></body></html>
\ No newline at end of file |