RE: [xsl] best practices re xsl:{import,include,next-match,apply-imports}
2008-05-07 15:52:31
No magic answer to this one. You could use apply-imports instead of
next-match - interesting to see that there is a use case for this. Is there
any reason the generic match="node()|@*" template can't be moved into the
generic stylesheet module?
Changing the import to include seems to me to be storing up other problems
for the future.
Michael Kay
http://www.saxonica.com/
-----Original Message-----
From: James A. Robinson [mailto:jim(_dot_)robinson(_at_)stanford(_dot_)edu]
Sent: 07 May 2008 16:44
To: XSL-List
Subject: [xsl] best practices re
xsl:{import,include,next-match,apply-imports}
Hi folks,
For the first time I've had an application where I think
xsl:next-match or xsl:apply-imports might applicable.
This application needs to be able to transform various
elements in various schema into be a fairly complicated
atom:entry format (where atom is the Atom Syndication Format,
http://www.w3.org/2005/Atom) which we have developed to
indicate hyperlinking relationships. The constructions of
the atom:entry takes 15 variables into account when it constructed.
A specific example is the need to transform an element from
the NLM Journal Publishing DTD, the relateed-article element
into this format.
Many of the 15 variables used to create the atom:entry are
generic when dealing with a related-article element. Two are not.
I thought it'd be nice to keep construction of these entries
as simple as possible for the people who will be maintaining
these stylesheets.
Specificaly I want to make it simple to add new templates for
transforming new types of related-article elements into these
atom:entry forms.
I thought what I would do is create a generic library
stylesheet with a callable template which takes 15 tunneled
parameters and creates the proper atom:entry.
Then I would create a stylesheet which matches on any
"related-article"
element, using a priority of 1, which called the library
template, constructing and passing along those tunneled
parameters which are generic (i.e., all those parameters
which are applicable to all related-article elements).
Finally, I wanted to add a last stylesheet with very specific
"related-article" element match, one which matched on
specific attributes, and which had a priority of 2. This top
level stylesheet would use xsl:next-match to tunnel through
the one or two parameters which weren't handled by the more
generic layer.
So I'd have
xsl:template match="related-article[...predicates...]" priority="2"
-> xsl:next-match w/ tunneled 2 parameters
xsl:template match="related-article" priority="1"
-> xsl:call-template w/ 13 tunneled parameters
xsl:template name="atom:hyperlink"
xsl:param ...13 tunneled parameters ...
<atom:entry>...</atom:entry>
This is the first time I'd used xsl:next-match, and I found
myself being confounded by how one should use xsl:import vs.
xsl:include or should use xsl:next-match vs. xsl:apply-imports.
My first reaction was that one should use xsl:import and
xsl:next-match to offer the most flexibility re future
changes. E.g., introduction of overridable variables or the
need to "next-match" at various priorities within the highest
level stylesheet.
What I've realized is that the rules of xsl:import and
xsl:next-match and how XSLT defines the next-match, by lower
priority -or- by lower precedence, means I run into trouble
if I introduce a template which suppresses the default
behavior of XSLT to print the string value of elements as it
walks the tree.
To try and boil this down to a simple set of examples, let's
say I have three stylesheets and a source document:
(1) A named template stylesheet, t.xsl.
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:template name="t">
<xsl:param name="a" as="xs:string?" tunnel="yes" />
<xsl:param name="b" as="xs:string?" tunnel="yes" />
<xsl:message select="concat('t: ',
string-join(($a,$b), ', '))"/>
</xsl:template>
</xsl:stylesheet>
(2) A "generic" stylesheet, g.xsl, which matches on an element 't' and
calls the named template in (1) with a tunneled parameter.
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:import href="t.xsl"/>
<xsl:template mode="t" match="t" priority="1">
<xsl:call-template name="t">
<xsl:with-param name="a" select="'g'" tunnel="yes"/>
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>
(3) A "specific" stylesheet, s.xsl, which assumes it can fall-back to
templates in (2) with a tunneled parameter.
Because it is processing a source document filled with other
elements and text nodes, it also contains a generic match to
navigate the document while surpressing default XSLT behavior.
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:import href="g.xsl"/>
<xsl:template mode="t" match="@*|node()">
<xsl:apply-templates mode="#current"/>
</xsl:template>
<xsl:template mode="t" match="t[(_at_)specific eq 'yes']"
priority="2">
<xsl:next-match>
<xsl:with-param name="b" select="'s'" tunnel="yes"/>
</xsl:next-match>
</xsl:template>
</xsl:stylesheet>
(4) A source document with a lot of text nodes in it, none of which I
want to have emitted. I just want a final result of an
xsl:message ('t: g, s') to be emitted.
<x>text<y>text<t specific="yes"/>text</y>text</x>
Because (3) has a template match "@*|node()", which is lower
precedence, the xsl:next-match won't ever fall back to (2).
This means I have to make one of the following changes to (3):
(a) change the xsl:import to xsl:include.
(b) change the xsl:next-match to xsl:apply-import.
(c) not use a generic match="@*|node()", require that callers
specifically target the elements to be processed
I'm wondering if there are any other options available? If
not, is there one of those which the developers here would
recommend as being likely to be better for long term maintenance?
I'm disclined to choose (c). The problems I have with (a)
and (b) are that they seem to imply a limitation in later
flexibility of the stylesheets (e.g., having parameters w/
the same name but different precedence in (2) and (3), or
allowing for xsl:next-match to work on templates introduced into (3))
My inclination, at this point, is that it will be better to
use xsl:include and require that both generic and specific
template matches have their priorities renumbered as new
functionality as added.
I'd appreciate any thoughts on this from you folks!
Thank you,
Jim
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
James A. Robinson
jim(_dot_)robinson(_at_)stanford(_dot_)edu
Stanford University HighWire Press http://highwire.stanford.edu/
+1 650 7237294 (Work) +1 650 7259335 (Fax)
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail:
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--
Previous by Date: |
RE: [xsl] Newbie wants comments too . . ., Scott Trenda |
Next by Date: |
Re: [xsl] best practices re xsl:{import,include,next-match,apply-imports}, James A. Robinson |
Previous by Thread: |
[xsl] best practices re xsl:{import,include,next-match,apply-imports}, James A. Robinson |
Next by Thread: |
Re: [xsl] best practices re xsl:{import,include,next-match,apply-imports}, James A. Robinson |
Indexes: |
[Date]
[Thread]
[Top]
[All Lists] |
|
|