LISTSERV mailing list manager LISTSERV 15.5

Help for XML-L Archives

XML-L Archives

XML-L Archives


Next Message | Previous Message
Next in Topic | Previous in Topic
Next by Same Author | Previous by Same Author
Chronologically | Most Recent First
Proportional Font | Monospaced Font


Join or Leave XML-L
Reply | Post New Message
Search Archives


Re: XSL question


"John E. Simpson" <[log in to unmask]>


General discussion of Extensible Markup Language <[log in to unmask]>


Wed, 13 Dec 2000 09:35:46 -0500





text/plain (144 lines)

At 06:12 PM 12/13/2000 +0530, Verma, Sanjay wrote:
>My xsl file is
><?xml version="1.0" ?>
><xsl:stylesheet xmlns:xsl=""
><xsl:output method="html"/>
><xsl:template match="/">

You're off to a good start with your <xsl:stylesheet> element -- using the
version attribute and the correct (most up-to-date) namespace declaration.
However, there's only one template rule in your stylesheet. Translated into
English, the template rule tells the XSLT processor (MSXML/IE5, Saxon,
whatever): "When you find the source document's root node, do nothing."

(Actually, it's not quite "nothing." There's whitespace between the
xsl:template's start and end tags... but ONLY whitespace. No matter how
your XSLT processor handles a whitespace-only result tree, the practical
effect when viewed in a browser is the same: whitespace only.)

First, try this. Replace the empty template rule above with one that looks
like this:

    <xsl:template match="/">
             <title>Regional Sales</title>

What this template tells the processor is: "When you find the source
document's root node, create [i.e., 'instantiate'] in the result tree
[i.e., what the browser will display] the general framework of an HTML
document, including html, head, title, and body elements. *Within the
result tree's body element*, look for and process all template rules
applying to children of the context node [in this case, the root node]; if
there are no explicit template rules for processing those children, then
use any built-in template rules in effect."

What IE will show you as a result is a document window with the title
"Regional Sales," and whose content consists of all the text nodes in the
XML source document, sort of butted up against one another in a big string.

What's going on at this point is that, in the absence of any template rules
for processing element and text nodes found in the source document, the
built-in rules kick in. The applicable built-in rules look something like this:

    <!-- [1] For element nodes: -->
    <xsl:template match="*">

    <!-- [2] For text nodes: -->
    <xsl:template match="text()">
       <xsl:value-of select="."/>

Template rule [1] says: "When you find an element in the source tree,
regardless of its name [note the wildcard asterisk where you'd normally see
a specific name], look for and apply all template rules (including built-in
ones) for all children of this element."

Your source document's non-empty elements have two kinds of children: other
elements, and text nodes. The other elements will be recursively processed
by this built-in rule [1]. As for text nodes, they'll be handled by
built-in rule [2], which says: "When you find a text node in the source
tree, simply transfer its contents to the result tree."

Bottom line is that (to this point) what you see in the browser is the same
as if it had been delivered a plain-old HTML document which looks like this:
          <title>Regional Sales</title>
          Northwind.comRegional Sales ReportSales report for the West
Coast, Central [etc., through:] East Coast

In order to make this a little more presentable, you'd want to provide
template rules for specific element types. For instance:

    <xsl:template match="sales">
       <h1><xsl:value-of select="summary/heading"/></h1>
       <h2><xsl:value-of select="summary/subhead"/></h2>
       <h4><xsl:value-of select="summary/description"</h4>

    <xsl:template match="data">
       <table border="1">

    <xsl:template match="region">
          <th colspan="4"><xsl:value-of select="name"/><th>
          <xsl:for-each select="quarter">
               <td><xsl:value-of select="@widgets-sold"/></td>

I'll leave for you the exercise of figuring out what each of these template
rules does. :)

There's one other template rule I like to include in my stylesheets, and
this is strictly a matter of taste:
    <xsl:template match="* | text()"/>
What this does is basically to override the built-in template rules for
elements and text nodes, by *suppressing* all text output from any of those
nodes. Thus, the only output (source tree) I'll see is the output I
explicitly put there with specific template rules.

Hope that helps.

P.S. I haven't tested any of the above XSLT code, but it should be okay
except possibly for stray typos. Also note that there are any number of
possible result trees which can reasonably be generated for a given source
tree. For instance, the above builds one table which contains all regions'
results; you could just as well build a separate table for each region, or

John E. Simpson | "He asked me if I knew what | time it was. I said, 'Yes, but
XML Q&A: | not right now.'" (Steven Wright)

Back to: Top of Message | Previous Page | Main XML-L Page



CataList Email List Search Powered by the LISTSERV Email List Manager