Re: [xsl] Question on <xsl:apply-templates>

Subject: Re: [xsl] Question on <xsl:apply-templates>
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx>
Date: Thu, 30 Oct 2003 18:30:22 -0500

The solution

<xsl:template mode="toc" match="text()"/>

will work, but it also closes a door you may not want to close. By suppressing all text nodes, you effectively set it up so that in order to get text, you can't let the stylesheet just do its thing anymore, but have to ask explicitly for values of nodes all the time to get them to show up. (I bet you have value-of instructions in your stylesheet now to get your output, since you can't simply rely on the default node traversal to give you your values.)

This may be okay if the stylesheet is a one-off; but if you're writing code that has to be maintained and extended if/as schemas and/or documents evolve, it's going to make things complicated -- potentially quite complicated.

The reason David's solution,

<xsl:template mode="toc" match="*"/>

doesn't work for you is that this template is probably matching some element node (or more than one) higher in the hierarchy than the ones whose value you want. Accordingly, when that element is matched, the processor's recursive tree-descent stops at that point, and lower-level elements aren't getting processed. If you provided the higher-level elements with overrides of this override, telling them to apply templates to their children, it would work again. (David knows this, and undoubtedly provides for it when he uses modes to do this kind of thing; he just forgot to warn you.)

A simpler solution, which also provides a good balance between robustness and maintainability, is the one Dimitre suggested in his reply to your original post. If you simply "reach down" by specifying a select expression on your apply-templates, the processor can pick up just the nodes you want, and skip the others.

Yet another way to go is to suppress only those elements you want not to show up, as in

<xsl:template mode="toc" match="p | list | figure"/>

I hope this helps. As usual, the correct solution is impossible to find in the dark: the only way to solve these problems entails understanding the XSLT processing model.


At 05:18 PM 10/30/2003, you wrote:

I tried your code and I got no output. I started looking up what your
idea was doing, and it matches every node. So if you use:

<xsl:template mode="toc" match="*"/>

Then I started thinking more, I knew you were onto something, so I
finally stumbled across it in a book. I wanted to use (and did):

<xsl:template mode="toc" match="text()"/>

This outputs nothing for every text node.

Wendell Piez                            mailto:wapiez@xxxxxxxxxxxxxxxx
Mulberry Technologies, Inc.      
17 West Jefferson Street                    Direct Phone: 301/315-9635
Suite 207                                          Phone: 301/315-9631
Rockville, MD  20850                                 Fax: 301/315-8285
  Mulberry Technologies: A Consultancy Specializing in SGML and XML

XSL-List info and archive:

Current Thread