XSL: recursive template call (using different predicates)

T

tthunder

Hi @all,

I have a trivial question, but I cannot find any answer :(

<xsl:template match="note">
<b>Note:</b>
</xsl:template>
<xsl:template match="note[@role = 'para']">
<p><!-- CALL <xsl:template match="note"> FROM HERE --></p>
</xsl:template>

Please have a look at this tiny piece of code. How can I call the
first template from the second specialized one?

NOTE: I cannot change the first one!

Many thanks,
Kirsten
 
M

Martin Honnen

I have a trivial question, but I cannot find any answer :(

<xsl:template match="note">
<b>Note:</b>
</xsl:template>
<xsl:template match="note[@role = 'para']">
<p><!-- CALL <xsl:template match="note"> FROM HERE --></p>
</xsl:template>

Please have a look at this tiny piece of code. How can I call the
first template from the second specialized one?

NOTE: I cannot change the first one!

Well if your sample XML has e.g.
<note role="para">
<note/>
</note>
then <xsl:apply-templates/> or <xsl:apply-templates select="note"/> will
do. But if you do not have nested note elements then it is not possible,
unless you name the first template.
 
J

Joseph Kesselman

As Martin said, the simplest solution is to use the xsl:call-template
operation and give the template you want to call a name.

Similar things can be accomplished with modes, but that would be
overkill for this simple case.
 
T

tthunder

As Martin said, the simplest solution is to use the xsl:call-template
operation and give the template you want to call a name.

Similar things can be accomplished with modes, but that would be
overkill for this simple case.

I am really surprised that this cannot be done (easily).

My structure is like this:

<note role="para">
I hope it works.
</note>

What I want is:
1. <xsl:template match="note[@role = 'para']"> is executed
2. <xsl:template match="note"> is executed

Of course, for the same element.

Background:
I am trying to print additional letters, if role="para" without
loosing the ability of "<xsl:template match="note">".
My use case is not that simple. I use DocBook XSL and I wanna modify
the output of a simple element ("note"), if I use a special role.
However, the DocBook XSL rule for "note" must be executed as well.
 
J

Joseph Kesselman

1. <xsl:template match="note[@role = 'para']"> is executed
2. <xsl:template match="note"> is executed

In addition to the two options I pointed out... It sounds like this is a
perfect opportunity to learn about the apply-imports operation. Write
your stylesheet so it imports the DocBook stylesheet that defines #2
above, and write your new #1 template so it calls <xsl:apply-imports> at
the point where you want to hand off to DocBook's standard processing.

That's about as close as XSLT comes to OOP-style inheritance and super()
invocation.
 
D

David Carlisle

As Martin said, the simplest solution is to use the xsl:call-template
operation and give the template you want to call a name.

Similar things can be accomplished with modes, but that would be
overkill for this simple case.

I am really surprised that this cannot be done (easily).

My structure is like this:

<note role="para">
I hope it works.
</note>

What I want is:
1. <xsl:template match="note[@role = 'para']"> is executed
2. <xsl:template match="note"> is executed

Of course, for the same element.

Background:
I am trying to print additional letters, if role="para" without
loosing the ability of "<xsl:template match="note">".
My use case is not that simple. I use DocBook XSL and I wanna modify
the output of a simple element ("note"), if I use a special role.
However, the DocBook XSL rule for "note" must be executed as well.

If you can alter the first template to add a name attribute then you can go

<xsl:template match="note" name="foo">
....
<xsl:template match="note[@role = 'para']">
stuff
<xsl:call-template name="foo"/>


if you are in a position that you have write access to the second
template but not the first (because you are over-riding some public xslt
file for example) that is the exact use case for xsl:apply-imports as
others have mentioned.

in one file you have

<xsl:template match="note">

then in the file that imports this you have

<xsl:template match="note[@role = 'para']">
stuff
<xsl:apply-imports/>


If you are using xslt2 you can use <xsl:next-match/> instead of
<xsl:apply-imports/> which works (more or less) the same way, but
without the requirement that the templates are in separate files.

David
 
T

tthunder

I am really surprised that this cannot be done (easily).
My structure is like this:
<note role="para">
I hope it works.
</note>
What I want is:
1. <xsl:template match="note[@role = 'para']"> is executed
2. <xsl:template match="note"> is executed
Of course, for the same element.
Background:
I am trying to print additional letters, if role="para" without
loosing the ability of "<xsl:template match="note">".
My use case is not that simple. I use DocBook XSL and I wanna modify
the output of a simple element ("note"), if I use a special role.
However, the DocBook XSL rule for "note" must be executed as well.

If you can alter the first template to add a name attribute then you can go

<xsl:template match="note" name="foo">
...
<xsl:template match="note[@role = 'para']">
stuff
<xsl:call-template name="foo"/>

if you are in a position that you have write access to the second
template but not the first (because you are over-riding some public xslt
file for example) that is the exact use case for xsl:apply-imports as
others have mentioned.

in one file you have

<xsl:template match="note">

then in the file that imports this you have

<xsl:template match="note[@role = 'para']">
stuff
<xsl:apply-imports/>

If you are using xslt2 you can use <xsl:next-match/> instead of
<xsl:apply-imports/> which works (more or less) the same way, but
without the requirement that the templates are in separate files.

David

--http://dpcarlisle.blogspot.com- Zitierten Text ausblenden -

- Zitierten Text anzeigen -

Nice!

<xsl:apply-imports/> and <xsl:next-match/> really work for my problem!

I saw "apply-imports" already, but didn't expect that it works for me.
I thought that there must be a generic solution which is independent
from "imports". I guess, that is why next-match was introduced in
XSLT2.

Thank you!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,008
Messages
2,570,269
Members
46,869
Latest member
TresaMcGir

Latest Threads

Top