Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 303
  • Last Modified:

Multiple Template Modes with XSLT 1.0

From what I understand, it is possible to use multiple template modes when using XSLT 2.0 but somehow I need to emulate that very same functionality using XSLT 1.0.

Essentially I am trying to achieve something like the following:
<!-- Some example content -->
<xsl:template select="something" mode="a">
  <span>Content A</span>
</xsl:template>
<xsl:template select="something" mode="a b">
  <span>Content B</span>
</xsl:template>
 
<!-- Contains all types of content -->
<xsl:template select="complex-content-area">
  <xsl:apply-templates select="something" mode="a b" />
</xsl:template>
 
<!-- Only supports a limited range of content -->
<xsl:template select="simple-content-area">
  <xsl:apply-templates select="something" mode="a" />
</xsl:template>
 
 
<!-- The following would NOT work because I want to maintain the original ordering -->
 
<xsl:template select="complex-content-area">
  <xsl:apply-templates select="something" mode="a" />
  <xsl:apply-templates select="something" mode="b" />
</xsl:template>

Open in new window

0
numberkruncher
Asked:
numberkruncher
  • 7
  • 6
1 Solution
 
Geert BormansCommented:
No you can't as far as I know

note that this is illegal in XSLT2 too
    <xsl:apply-templates select="something" mode="a b"  />

This is legal in XSLT2, but not in XSLT1
    <xsl:template match="something" mode="a b">

I recommend that you have a mode "ab" where you make the combination for a and b
A bit clumsy... but still




0
 
numberkruncherAuthor Commented:
Something like the following? The problem is there are a lot of different content nodes, but some only apply to the more complex section type.

I was reading some XSLT answers the other day on this website, and I came across one where you suggested to someone to use Saxon for XSLT 2. Is Saxon still the only real option, or are there any newcomers since your post (which was in 2007 if I remember correctly). I am still unable to use XSLT 2 for this project, but I want to have a play around with the later version for future projects.
<!-- Only define the content once -->
<xsl:template name="content-a">
  <span>Content A</span>
</xsl:template>
<xsl:template name="content-b">
  <span>Content B</span>
</xsl:template>
 
<!-- Individual content for a -->
<xsl:template match="something_alt1" mode="a">
  <xsl:call-template name="content-a" />
</xsl:template>
<!-- Individual content for b -->
<xsl:template match="something_alt2" mode="b">
  <xsl:call-template name="content-b" />
</xsl:template>
 
<!-- Individual content which applies to a or b -->
<xsl:template match="something_alt1" mode="ab">
  <xsl:call-template name="content-a" />
</xsl:template>
<xsl:template match="something_alt2" mode="ab">
  <xsl:call-template name="content-b" />
</xsl:template>

Open in new window

0
 
Geert BormansCommented:
Saxon is still the only real option,
XML Spy is too buggy and too slow
there is also Gestalt.... but I would go for Saxon (it is the fastest and most standardised)
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
Geert BormansCommented:
well, about your code sample....
the earliest one was using select templates, the new example uses named templates.
If all of this is for named templates, just pass an extra parameter and you don't need modes.
You can by the way also pass parameters with apply-templates
(just make sure you tunnel them explicitely)

You seem to be abusing modes a little bit here,
it is not completely clear to me what you want to do
0
 
numberkruncherAuthor Commented:
Essentially I require XML input to have a caption block similar to the following which can hold any type of content, and has an associated label. The label area can only contain certain types of content.

Take the following for example:
<caption>
   <content>
      <!-- All types of content can go here -->
      <heading>Some heading text<cite ref="ref1" /></heading>
   </content>
   <label>
       <!-- Limited range of content can go here, for example, heading is not supported here, but cite is -->
       Some label text<cite ref="ref1" />
   </label>
</caption>

Open in new window

0
 
Geert BormansCommented:
You don't need modes for that,
you could essentially just check the ancestor
ancestor::content
ancestor::label
and make decissions based on that
That could be a little bit slower, but it would be a lot more elegant

not testing for the ancestor, but using it in the template match will even be faster
and more elegant
<xsl:template match="content/cite">...
0
 
numberkruncherAuthor Commented:
I have been using the ancestor to compare (in terms of your second example), but that confines me to only being able to have content inside a content tag. There are several other simple formatting tags and which I need to support.

The example I gave above couldn't have worked, after giving it some more thought I have realized that it is introducing a load of additional overhead, to move the same problem elsewhere.

I think that something like the following might work. Here I am using apply-templates for most of the work, but where the same content is required in both simple and complex modes, I am using call-template to remove the need to duplicate content.

I can see how comparing the parent node with an xsl:choose tag could work, but that would instantly add a lot of bulk to my XSLT file. Probably not a major issue performance wise, but it could add some maintenance issues.

Thanks for the status update on XSLT support. A book which I ordered on XSLT 2 has literally just arrived, so I shall download the open source version for a play later tonight :)

<xsl:template match="caption" mode="complex">
	<xsl:apply-templates />
</xsl:template>
 
<xsl:template match="caption/content">
	<xsl:apply-templates mode="complex" />
</xsl:template>
<xsl:template match="caption/label">
	<xsl:apply-templates mode="simple" />
</xsl:template>
 
<xsl:template match="cite" mode="simple">
  <xsl:call-template name="render-cite" />
</xsl:template>
<xsl:template match="cite" mode="complex">
  <xsl:call-template name="render-cite" />
</xsl:template>
 
<xsl:template name="render-cite">
  <!-- Cite content goes here -->
</xsl:template>
<xsl:template match="heading" mode="complex">
	<h1>
		<xsl:apply-templates mode="simple" />
	</h1>
</xsl:template>

Open in new window

0
 
numberkruncherAuthor Commented:
Sorry, EE has used my tags to format itself, the line should have read:

There are several other simple formatting tags <b> <i> <u> and  which I need to support.

bold, italic, and underline tags (just in case the above entity characters are not shown)
0
 
Geert BormansCommented:
well, I don't like call-templates in locations that I feel could be dealt with using simple apply-templates
Though a bit slower, but a lot more maintenance friendly
<xsl:template match="content//b">...
or
<xsl:template match="b[ancestor::content]">...
0
 
numberkruncherAuthor Commented:
That's interesting; so does apply-templates work more efficiently than call-template then? Or is it the design topology that you prefer?

I think that I can make the second of those alternatives work, but it is going to be a fairly long condition. Does a long condition like this make a massive difference to the overall performance?


0
 
Geert BormansCommented:
It is the design topology I prefer,
for me it is more clear what is passed as a context to apply-templates
I feel call-templates more of being for building function-like thingies, not having to deal straight away with nodes
(as long as you don't have to copy/paste too much code doing it that way)
0
 
numberkruncherAuthor Commented:
Thanks for your help Gertone!! I think that has answered my question.
0
 
Geert BormansCommented:
welcome
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

  • 7
  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now