Re: [xsl] Multiple recursive transforms using document function?

Subject: Re: [xsl] Multiple recursive transforms using document function?
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Mon, 30 Apr 2001 22:09:37 +0100
Hi Rowell,

I'll just explain what's going on in your stylesheet, and hopefully
that will help you understand the problem.

The processor first works on files.xml - it gets the root node of
files.xml, applies the built-in template to that, which selecting the
child 'files' element and applying templates to that. That again
selects the child 'file' elements and applies templates to them.  The
processor finds a template to match the file elements:

> <xsl:template match="file">
>     <xsl:apply-templates select="document(.)"/>
> </xsl:template>

Here, you get the root node of the document specified by the file
element.  The first document is 'template.xml'.  So the processor
takes the root node of that document, and applies templates to it.
The built in templates makes the processor recurse down the tree.
Eventually it gets to the row1 element, which matches the following

> <xsl:template match="row1">
>     <div><xsl:value-of select="row1"/></div>
>     <span><xsl:value-of select="//name"/></span>
> </xsl:template>

So the processor creates the 'div' element.  Inside, it tries to add
the value of the 'row1' child element of the current node (i.e. the
row1 element).  It then creates the 'span' element, and tries to add
as the value the (first) name element descendant of the root node of
the *current document* (which is, of course, the 'template.xml'

The 'row2' element is matched and processed in a very similar way.
Starting an expression with / always gives an absolute path from the
root node of the document containing the current node.

It's probably best for you to apply templates to only the first file
element in files.xml:

<xsl:template match="files">
   <xsl:apply-templates select="file[1]" />

Then store the second file in a global variable:

<xsl:variable name="dictionary" select="document(/files/file[2])" />

You can then access the name and vendor from the dictionary by
indexing into the $dictionary variable within the templates matching
row1 and row2:

<xsl:template match="row1">
   <div><xsl:value-of select="." /></div>
   <span><xsl:value-of select="$dictionary/dictionary/name" /></span>

<xsl:template match="row2">
   <div><xsl:value-of select="." /></div>
   <span><xsl:value-of select="$dictionary/dictionary/vendor" /></span>

It's not clear from your example how 'template.xml' and
'dictionary.xml' tie up together, but you may be able to use more
general templates for it.

> BTW. The data in the examples I used are simplified to illustrate
> the problem. The real files are a bit more involved, but they use
> essentially the same idea.

If the above technique doesn't work because of the complexity of the
real files, then do give a more complex example and we'll see what we
can do.

I hope that helps,


Jeni Tennison

 XSL-List info and archive:

Current Thread