Subject: RE: [xsl] best practices re xsl:{import,include,next-match,apply-imports} From: "Michael Kay" <mike@xxxxxxxxxxxx> Date: Wed, 7 May 2008 23:51:49 +0100 |
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.robinson@xxxxxxxxxxxx] > 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[@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.robinson@xxxxxxxxxxxx > Stanford University HighWire Press http://highwire.stanford.edu/ > +1 650 7237294 (Work) +1 650 7259335 (Fax)
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] best practices re xsl:{impor, James A. Robinson | Thread | RE: [xsl] best practices re xsl:{i, Wendell Piez |
RE: [xsl] Newbie wants comments too, Wendell Piez | Date | Re: [xsl] best practices re xsl:{i, James A. Robinson |
Month |