This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Nested/embedded/self-referential path expressions.


Hi Ed,

>> In general it's a bad idea to use complicated conditions like this
>> within patterns; you'd probably be better off having a general
>> template for all elements within Row elements, but only applying
>> templates to those that share a name with a column:
>> 
>> <xsl:template match="Row">
>>   <xsl:apply-templates select="*[key('columns', name())]" />
>> </xsl:template>
>> 
>> <xsl:template match="Row/*">
>>   ...
>> </xsl:template>
>
> Seems as though the pattern in the "select" is darn near as complex
> as the match: "*[key('columns', name())]" versus
> "Row/*[key('columns', name())]". Did we actually gain much ground
> here? Are there underlying reasons why complexity in the "select" is
> preferred over the "match"?

It might be a superstition on my part, but I think so. When you tell a
processor to apply templates to a bunch of nodes, it has to first
create the bunch of nodes, then for each of them go through the
templates in the stylesheet to work out which of the templates to use
with it. Working out which template to use with a particular node
could be quite arduous, because there might be lots of templates that
could potentially match, even if they're discarded quickly. So if you
can cut down on the number of nodes that the processor has to try to
match, this seems like a good thing, as does making it easy to tell
whether a node matches a template or not.

A second advantage in some cases is that within a select attribute you
have full access to the power of XPath (and indeed XSLT, since you can
declare variables within the template prior to selecting the nodes),
whereas within a match attribute (a pattern) you're somewhat limited,
especially by not being able to refer to variables. It's generally
easier to get together the nodes that you want to apply templates to
than it is to match them.

Another thing that comes to mind is the fact that when you apply
templates to everything and manage processing by matching only some of
them, you still have to worry about what happens to those that don't
get matched, which means more templates and can make the stylesheet
harder to maintain (if you have templates that explicitly match the
"others" and then change the nodes that you want to match) or
expensive to run (if you have a low-level template that ensures no
text gets out and use the built-in templates to do default processing
down to that level).

The other reason that it's a good thing to select only the nodes you
want to process is that this means that the position() of the nodes is
correct, which can help if you need to number them or put separators
after all but the last and so on.

I also find it makes stylesheets look cleaner, to my eyes (at least
when you're dealing with content that's predictable).

> What I decided to do (although I may change given your feedback) is
> two templates and modes: one template to filter the columns, other
> templates to process the filtered nodes:
>
> <xsl:templateatch="gnsl:Row/*">
>    <xsl:variable name="MyName" select="name()" />
>    <xsl:if test="$TableColumns[name()=$MyName]" >
>       <xsl:apply-templates select="." mode="ColumnContent" />
>    </xsl:if>
> </xsl:template>
>
> <xsl:template  mode="ColumnContent" match="gnsl:Row/*>
> ....
> </xsl:template>

OK. As above, the only thing you have to be careful of here is that
the position() of the element-within-Row in the ColumnContent mode
template will always be 1, so you won't be able to use that to e.g.
give alternate columns different background colours.

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]