XSL: recursive template call (using different predicates)

Discussion in 'XML' started by tthunder@gmx.de, May 29, 2007.

  1. Guest

    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
    , May 29, 2007
    #1
    1. Advertising

  2. wrote:

    > 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.

    --

    Martin Honnen
    http://JavaScript.FAQTs.com/
    Martin Honnen, May 29, 2007
    #2
    1. Advertising

  3. 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.

    --
    Joe Kesselman / Beware the fury of a patient man. -- John Dryden
    Joseph Kesselman, May 29, 2007
    #3
  4. Guest

    On 29 Mai, 19:00, Joseph Kesselman <> wrote:
    > 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.
    >
    > --
    > Joe Kesselman / Beware the fury of a patient man. -- John Dryden


    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.
    , May 29, 2007
    #4
  5. wrote:
    > 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.



    --
    Joe Kesselman / Beware the fury of a patient man. -- John Dryden
    Joseph Kesselman, May 29, 2007
    #5
  6. Joseph Kesselman, May 29, 2007
    #6
  7. wrote:
    > On 29 Mai, 19:00, Joseph Kesselman <> wrote:
    >> 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.
    >>
    >> --
    >> Joe Kesselman / Beware the fury of a patient man. -- John Dryden

    >
    > 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
    David Carlisle, May 29, 2007
    #7
  8. Guest

    On 29 Mai, 22:54, David Carlisle <>
    wrote:
    > wrote:
    > > On 29 Mai, 19:00, Joseph Kesselman <> wrote:
    > >> 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.

    >
    > >> --
    > >> Joe Kesselman / Beware the fury of a patient man. -- John Dryden

    >
    > > 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!
    , May 30, 2007
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alfraed
    Replies:
    0
    Views:
    805
    Alfraed
    Jul 14, 2003
  2. Soren Kuula
    Replies:
    2
    Views:
    562
    Malcolm Dew-Jones
    Apr 13, 2005
  3. Replies:
    1
    Views:
    3,600
    A. Bolmarcich
    May 27, 2005
  4. lele1979

    xsl:Include e xsl:call-template

    lele1979, Nov 6, 2006, in forum: XML
    Replies:
    1
    Views:
    559
  5. lele1979

    xsl:Include e xsl:call-template

    lele1979, Nov 6, 2006, in forum: XML
    Replies:
    0
    Views:
    363
    lele1979
    Nov 6, 2006
Loading...

Share This Page