Re: xsl:apply-imports?

Subject: Re: xsl:apply-imports?
From: James Clark <jjc@xxxxxxxxxx>
Date: Wed, 23 Dec 1998 11:23:14 +0700
Tyler Baker wrote:
> 
> In the latest XSL spec the following is defined:
> 
> "xsl:apply-imports processes the current node using only template rules
> that were imported into the stylesheet containing the current rule; the
> node is processed in the current rule's mode."
> 
> What happens when you nest apply-imports statements inside of each
> other, e.g.
> 
> <xsl:template match="foo">
>   <xsl:apply-imports>
>     <xsl:apply-templates/>
>     <xsl:apply-imports>
>        <xsl:apply-templates/>
>           <xsl:apply-imports>
>              <xsl:apply-templates/>
>              OK now what is the stylesheet context?
>           </xsl:apply-imports>
>       </xsl:apply-imports>
>   </xsl:apply-imports>
> </xsl:template>

xsl:apply-imports can't contain other elements:

<!ELEMENT xsl:apply-imports EMPTY>

The description in the WD needs expansion.  Here's a fuller description:

Imagine a tree with a node for the root and a node for each xsl:import
element, where each node has an associated list of template rules.
I'll call these nodes import-nodes to distinguish them from XML nodes.
Number the import-nodes in the tree in a post-order traversal (ie
number children before a parent).  Associate each template rule with
the number of its import-node.  Also build a vector that for each
import-node number gives the number of its lowest-numbered
descendant import-node.  Define a template rule Y to be a
_subordinate_ of a template rule X if

1. the import-node number of X is > the import-node number of Y, and

2. the import-node number of Y is >= the import-node number of the
lowest-numbered descendant of X, and

3. X and Y either both don't have a mode or both have the same mode

In the course of processing, maintain a stack of {node, template rule}
pairs, corresponding to the template rules that are being run (this
stack is also needed for loop detection).

To implement xsl:apply-templates look at the top-most entry on the
stack.  Find the best template rule that is a subordinate of the
template rule on the top of the stack; if there's no such rule, use
the built-in rule.  Process the node on the top of the stack using
this template rule.

For example, given a stylesheet 1.xsl:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl";>

<xsl:import href="2.xsl"/>

<xsl:template match="foo">
 <foo1><xsl:apply-imports/></foo1>
</xsl:template>

<xsl:template match="bar">
 <bar1><xsl:apply-imports/></bar1>
</xsl:template>

</xsl:stylesheet>

where 2.xsl is

<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl";>

<xsl:import href="3.xsl"/>

<xsl:template match="foo">
 <foo2><xsl:apply-imports/></foo2>
</xsl:template>

<xsl:template match="bar">
 <bar2><xsl:apply-imports/></bar2>
</xsl:template>

</xsl:stylesheet>

and 3.xsl is

<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl";>

<xsl:template match="bar">
 <bar3><xsl:apply-imports/></bar3>
</xsl:template>

</xsl:stylesheet>

and a source document:

<foo>A<bar>B<foo>C<bar/>D</foo>E</bar>F</foo>

The result will be

<foo1><foo2>A<bar1><bar2><bar3>B<foo1><foo2>C<bar1><bar2><bar3/></bar2></bar1>D</foo2></foo1>E</bar3></bar2></bar1>F</foo2></foo1>

James


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread