tags:

views:

51

answers:

1

My original idea about apply-imports was that if there are two templates which matches the same node, then using apply-imports in a template with higher priority runs the template with the lower priority. But I recently find out that it's important how are imports organized.

Two cases interests me particularly.

  • Will apply imports work on a template which is imported in imported file (nested import)?
  • How about a "sibling import" (master file imports two files with templates matching the same nodes)

It seems to me that this is not clearly described in specification. Could someone provide authoritative guidelines?

EDIT: I can try those cases on my own, but there is always a danger that it will be implementation specific behavior.

+1  A: 

I am not an XSLT expert (more of an enthusiast) but this was an interesting and so far unanswered question. I think the answer does lie in the specification but is a little perplexing, as you need to work out what post-order traversal is first.

http://en.wikipedia.org/wiki/Tree_traversal

There is an example in the specification of an "import precedence" tree:

http://www.w3.org/TR/xslt#dt-import-precedence

For example, suppose

  • stylesheet A imports stylesheets B and C in that order;
  • stylesheet B imports stylesheet D;
  • stylesheet C imports stylesheet E.

Then the order of import precedence (lowest first) is D, B, E, C, A.

You need to appreciate post-order traversal so that you can understand why the stylesheets have this import precedence order. The wikipedia characterizes post-order traversal as being "left, right, root".

In general, a definition or template rule with higher import precedence takes precedence over a definition or template rule with lower import precedence.

So back to your specific questions:

  • Will apply imports work on a template which is imported in imported file (nested import)?

My guess would be yes (according to precedence order) and it would even call multiple templates if you call them from inside the corresponding matching template. As described here:

http://www.w3.org/TR/xslt#element-apply-imports

For example, suppose the stylesheet doc.xsl contains a template rule for example elements:

<xsl:template match="example">
  <pre><xsl:apply-templates/></pre>
</xsl:template>

Another stylesheet could import doc.xsl and modify the treatment of example elements as follows:

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

<xsl:template match="example">
  <div style="border: solid red">
     <xsl:apply-imports/>
  </div>
</xsl:template>

The combined effect would be to transform an example into an element of the form:

<div style="border: solid red"><pre>...</pre></div>
  • How about a "sibling import" (master file imports two files with templates matching the same nodes)

The matching template will be chosen on the basis on having higher import precedence and this is determined by the import order.

My guess is it would work like this:

  • stylesheet A imports stylesheets B and C in that order;

Then the order of import precedence (lowest first) is B, C, A.

So in this case a template in stylesheet C would be chosen.

  • stylesheet A imports stylesheets C and B in that order;

Then the order of import precedence (lowest first) is C, B, A.

So in this case a template in stylesheet B would be chosen.

Mark McLaren
I think you are absolutely right in everything you write. You are however more concerned about precedence than about overall availability. For example nested import mostly works. But nobody said it explicitly. This is important, because I would expect the same behavior for sibling imports, but it mostly don't work. To give an example based on your example: if you call apply-imports in B, it does not (mostly) call template defined in C, although it matches the node! I have to find some time to try to apply your answer on my situation, I'm too busy now.
calavera.info