count recursiv name-templated calls

Discussion in 'XML' started by Philipp Kraus, Feb 26, 2013.

  1. Hello,

    I would like to work with XSLT (2.0). I have got code like

    <xsl:template name="item">
    <xsl:text>?? test</xsl:text>
    </xsl:template>


    and different matches in another file

    <xsl:template match="node1"
    <xsl:call-template name="item"/>
    </xsl:template>

    <xsl:template match="node2"
    <xsl:call-template name="item"/>
    </xsl:template>

    my XML document shows eg

    <node1>
    </node1>

    <node1>
    <node2>
    <node1/>
    </node2>
    </node1>

    I would like to push the number of the recursiv-template matches of the
    item template
    on the position of ??. In the example XML I will get the numbers 1, 1, 2, 3
    The item template should count itself the number of its recursiv calls

    Thanks a lot

    Phil
    Philipp Kraus, Feb 26, 2013
    #1
    1. Advertising

  2. On 2/26/2013 12:25 PM, Philipp Kraus wrote:
    > <xsl:text>?? test</xsl:text>


    > I would like to push the number of the recursiv-template matches of the
    > item template
    > The item template should count itself the number of its recursiv calls


    http://www.w3.org/TR/xslt20/#parameters

    (That's supported in XSLT 1.0 as well, of course.)

    Note that it's your responsibility to explicitly pass the parameter
    value down the template call/apply tree.

    I haven't checked, but examples can be undoubtedly be found at
    http://www.dpawson.co.uk/xsl/sect2/N5982.html

    For other kinds of counting, see
    http://www.dpawson.co.uk/xsl/sect2/N2018.html

    --
    Joe Kesselman,
    http://www.love-song-productions.com/people/keshlam/index.html

    {} ASCII Ribbon Campaign | "may'ron DaroQbe'chugh vaj bIrIQbej" --
    /\ Stamp out HTML mail! | "Put down the squeezebox & nobody gets hurt."
    Joe Kesselman, Feb 26, 2013
    #2
    1. Advertising

  3. On 2013-02-26 19:08:41 +0100, Joe Kesselman said:

    > On 2/26/2013 12:25 PM, Philipp Kraus wrote:
    >> <xsl:text>?? test</xsl:text>

    >
    >> I would like to push the number of the recursiv-template matches of the
    >> item template
    >> The item template should count itself the number of its recursiv calls

    >
    > http://www.w3.org/TR/xslt20/#parameters
    >
    > (That's supported in XSLT 1.0 as well, of course.)
    >
    > Note that it's your responsibility to explicitly pass the parameter
    > value down the template call/apply tree.
    >
    > I haven't checked, but examples can be undoubtedly be found at
    > http://www.dpawson.co.uk/xsl/sect2/N5982.html
    >
    > For other kinds of counting, see
    > http://www.dpawson.co.uk/xsl/sect2/N2018.html


    I have found the "tunnel" argument on the template, IMHO this can count
    the template calls,
    so I have modified my template to

    <xsl:template name="item">
    <xsl:param name="depth" select="$depth+1" tunnel="yes"/>
    <xsl:value-of select="$deph"/>
    <xsl:text> test</xsl:text>
    </xsl:template>

    so now I get the error, that depth is not initialized. How can I
    initialize and increment
    the tunnel parameter?

    Phil
    Philipp Kraus, Feb 26, 2013
    #3
  4. On 2013-02-26 19:08:41 +0100, Joe Kesselman said:

    > On 2/26/2013 12:25 PM, Philipp Kraus wrote:
    >> <xsl:text>?? test</xsl:text>

    >
    >> I would like to push the number of the recursiv-template matches of the
    >> item template
    >> The item template should count itself the number of its recursiv calls

    >
    > http://www.w3.org/TR/xslt20/#parameters
    >
    > (That's supported in XSLT 1.0 as well, of course.)
    >
    > Note that it's your responsibility to explicitly pass the parameter
    > value down the template call/apply tree.
    >
    > I haven't checked, but examples can be undoubtedly be found at
    > http://www.dpawson.co.uk/xsl/sect2/N5982.html
    >
    > For other kinds of counting, see
    > http://www.dpawson.co.uk/xsl/sect2/N2018.html


    I have got some problems to modify the code.
    I have a complex XSL file, in which are a lot of apply templates and a lot of
    call of my "item" template.

    I must create a plain text structure

    # section1
    ## section 2
    ### section 3

    # section 4

    On each call of my item template a counter must be increment, that counts the
    recursiv calls of the item template. Different XML nodes can be call
    the item template
    from different nodes on the XSL document, so IMHO the best solution is
    that my item
    template counts the recursiv calls.
    I can not use the XML structure, because my template calls are
    different because in some case
    if / chose calls are enable / disable the item template call.

    Phil
    Philipp Kraus, Feb 26, 2013
    #4
  5. Philipp Kraus <> writes:

    > On 2013-02-26 19:08:41 +0100, Joe Kesselman said:
    >
    >> On 2/26/2013 12:25 PM, Philipp Kraus wrote:
    >>
    >>> I would like to push the number of the recursiv-template matches of
    >>> the item template The item template should count itself the number
    >>> of its recursiv calls

    >>
    >> http://www.w3.org/TR/xslt20/#parameters

    [...]

    > I have found the "tunnel" argument on the template,


    Note to self: Oh my God... dynamic scoping in XSLT. It's turning mad...

    > IMHO this can count the template calls, so I have modified my template
    > to
    >
    > <xsl:template name="item">
    > <xsl:param name="depth" select="$depth+1" tunnel="yes"/>
    > <xsl:value-of select="$deph"/>
    > <xsl:text> test</xsl:text>
    > </xsl:template>


    select provides a default value, in case none is passed. So this won't
    work.

    You haven't shown us how you call the templates on node1 or node2.
    That's where all the work would go. AFAIU there is no need of tunneling
    here, or at least tunneling doesn't fit your requirements (tunnel just
    passes the values, you need them to be incremented).

    So, how do the recursive calls happen? In the following, I assume you
    have something like that:

    <xsl:template match="node1">
    <xsl:call-template name="item" select="."/>
    <xsl:apply-templates select="*"/> <!-- recurse -->
    </xsl:template>

    and the same for node2 (or match="node1|node2" on this template).

    Now let's add the "depth" parameter:

    <xsl:template match="node1">
    <xsl:param name="depth" select="0"/>
    <xsl:call-template name="item" select=".">
    <xsl:with-param name="depth" select="$depth"/>
    </xsl:call-template>
    <xsl:apply-templates select="*">
    <xsl:with-param name="depth" select="$depth+1"/>
    </xsl:template>
    </xsl:template>

    Note that select is used to provide zero if no parameter is passed to
    the "node1" template". This does the initialization. Of course you're
    free to pass whatever else you want (which is what happens for the
    potentially recursive calls done by <xsl:apply-templates>).

    AFAIU, using tunneling could save the first <xsl:with-param>. I'm not
    sure this is worth the trouble; you decide.

    BTW, if you want to know how many node1 or node2 are above the current
    node, you can use:

    <xsl:value-of
    select="count(ancestor::*[name()="node1" or name()="node2"])"/>

    or

    <xsl:value-of select="count(ancestor::node1)+count(ancestor::node2)"/>

    This is off by 1, use ancestor-or-self to consider also the current
    node. It also assumes no namespace is in use.

    -- Alain.
    Alain Ketterlin, Feb 27, 2013
    #5
  6. Alain Ketterlin wrote:

    > So, how do the recursive calls happen? In the following, I assume you
    > have something like that:
    >
    > <xsl:template match="node1">
    > <xsl:call-template name="item" select="."/>
    > <xsl:apply-templates select="*"/> <!-- recurse -->
    > </xsl:template>
    >
    > and the same for node2 (or match="node1|node2" on this template).
    >
    > Now let's add the "depth" parameter:
    >
    > <xsl:template match="node1">
    > <xsl:param name="depth" select="0"/>
    > <xsl:call-template name="item" select=".">
    > <xsl:with-param name="depth" select="$depth"/>
    > </xsl:call-template>


    I am confused, since then does "call-template" take a "select" attribute?

    http://www.w3.org/TR/xslt20/#named-templates does not show any.
    Martin Honnen, Feb 27, 2013
    #6
  7. Martin Honnen <> writes:

    > Alain Ketterlin wrote:


    >> <xsl:template match="node1">
    >> <xsl:param name="depth" select="0"/>
    >> <xsl:call-template name="item" select=".">
    >> <xsl:with-param name="depth" select="$depth"/>
    >> </xsl:call-template>

    >
    > I am confused, since then does "call-template" take a "select"
    > attribute?


    You know the answer: I've just invented this nonsense. Even if it
    existed it would be useless anyway since call-template doesn't change
    the current node.

    -- Alain.
    Alain Ketterlin, Feb 27, 2013
    #7
  8. On 2013-02-27 11:30:34 +0100, Alain Ketterlin said:

    > Philipp Kraus <> writes:
    >
    >> On 2013-02-26 19:08:41 +0100, Joe Kesselman said:
    >>
    >>> On 2/26/2013 12:25 PM, Philipp Kraus wrote:
    >>>
    >>>> I would like to push the number of the recursiv-template matches of
    >>>> the item template The item template should count itself the number
    >>>> of its recursiv calls
    >>>
    >>> http://www.w3.org/TR/xslt20/#parameters

    > [...]
    >
    >> I have found the "tunnel" argument on the template,

    >
    > Note to self: Oh my God... dynamic scoping in XSLT. It's turning mad...
    >
    >> IMHO this can count the template calls, so I have modified my template
    >> to
    >>
    >> <xsl:template name="item">
    >> <xsl:param name="depth" select="$depth+1" tunnel="yes"/>
    >> <xsl:value-of select="$deph"/>
    >> <xsl:text> test</xsl:text>
    >> </xsl:template>

    >
    > select provides a default value, in case none is passed. So this won't
    > work.
    >
    > You haven't shown us how you call the templates on node1 or node2.
    > That's where all the work would go. AFAIU there is no need of tunneling
    > here, or at least tunneling doesn't fit your requirements (tunnel just
    > passes the values, you need them to be incremented).


    Yes, I have seen at night. I have found a working solution

    http://saxon.sourceforge.net/saxon7.9.1/extensions.html#assignable

    so I can do this
    <xsl:variable name="listindent" select="0" as="xs:integer"
    saxon:assignable="yes"/>

    <xsl:template name="listitem">
    <xsl:param name="value"/>
    <xsl:param name="item" select="'*'"/>

    <xsl:call-template name="listindent"/>
    <saxon:assign name="listindent" select="$listindent+1"/>

    <xsl:value-of select="$item"/>
    <xsl:text> </xsl:text>
    <xsl:value-of select="$value"/>
    <xsl:call-template name="nl"/>

    <saxon:assign name="listindent" select="-1+$listindent"/>
    </xsl:template>

    If the $value also a listitem, the listindent stores the correct value,
    but it is a non-generic

    Phil
    Philipp Kraus, Feb 27, 2013
    #8
  9. On 2013-02-27 11:30:34 +0100, Alain Ketterlin said:

    > Philipp Kraus <> writes:
    >
    >> On 2013-02-26 19:08:41 +0100, Joe Kesselman said:
    >>
    >>> On 2/26/2013 12:25 PM, Philipp Kraus wrote:
    >>>
    >>>> I would like to push the number of the recursiv-template matches of
    >>>> the item template The item template should count itself the number
    >>>> of its recursiv calls
    >>>
    >>> http://www.w3.org/TR/xslt20/#parameters

    > [...]


    [...]

    >
    > <xsl:template match="node1">
    > <xsl:param name="depth" select="0"/>
    > <xsl:call-template name="item" select=".">
    > <xsl:with-param name="depth" select="$depth"/>
    > </xsl:call-template>
    > <xsl:apply-templates select="*">
    > <xsl:with-param name="depth" select="$depth+1"/>
    > </xsl:template>
    > </xsl:template>
    >
    > Note that select is used to provide zero if no parameter is passed to
    > the "node1" template". This does the initialization. Of course you're
    > free to pass whatever else you want (which is what happens for the
    > potentially recursive calls done by <xsl:apply-templates>).


    This would be my first try but I have posted a short example of my problem.
    The calls for the "item" template are within another XSL file, which can not be
    changed (at the moment), so I can modify only the item template and need
    the depth counter in this template.

    With your solution i must modify each item call and each apply call, is
    this correct?
    But in this way on each apply the depth counter will be increment, or does it?
    So $depth stores not the recursion depth of item but rather the depth
    of the apply calls,
    do I understand it correct?


    > BTW, if you want to know how many node1 or node2 are above the current
    > node, you can use:
    >
    > <xsl:value-of
    > select="count(ancestor::*[name()="node1" or name()="node2"])"/>
    >
    > or
    >
    > <xsl:value-of select="count(ancestor::node1)+count(ancestor::node2)"/>


    If I understand it correct, this value returns the depth of the "node
    recursion of my XML tree".

    In my problem, I want to count the recursiv call of a single template
    here item, so if the parser
    runs over my XML nodes and calls the item template and within the
    descent of the XML node item
    again, I will get the value 2, because item is recursive called twice.

    Phil
    Philipp Kraus, Feb 28, 2013
    #9
  10. On 2/27/2013 8:14 PM, Philipp Kraus wrote:
    > If I understand it correct, this value returns the depth of the "node
    > recursion of my XML tree".
    > In my problem, I want to count the recursiv call of a single template


    That was my understanding, which is why I pointed you to parameters.

    Many "counting" tasks in XSLT really are better handled by using the
    numbering facilities designed into the language -- but those are
    generally focused on enumerating positions in the document tree rather
    than call depth, so they wouldn't have been the right answer for the
    question you asked.

    --
    Joe Kesselman,
    http://www.love-song-productions.com/people/keshlam/index.html

    {} ASCII Ribbon Campaign | "may'ron DaroQbe'chugh vaj bIrIQbej" --
    /\ Stamp out HTML mail! | "Put down the squeezebox & nobody gets hurt."
    Joe Kesselman, Feb 28, 2013
    #10
  11. On 2013-02-28 04:09:54 +0100, Joe Kesselman said:

    > On 2/27/2013 8:14 PM, Philipp Kraus wrote:
    >> If I understand it correct, this value returns the depth of the "node
    >> recursion of my XML tree".
    >> In my problem, I want to count the recursiv call of a single template

    >
    > That was my understanding, which is why I pointed you to parameters.
    >
    > Many "counting" tasks in XSLT really are better handled by using the
    > numbering facilities designed into the language -- but those are
    > generally focused on enumerating positions in the document tree rather
    > than call depth, so they wouldn't have been the right answer for the
    > question you asked.


    Do you know another possibility without parameter, because I try to
    decide about a redesign over the "calling XSL" and change all apply
    calls
    with the depth paramer. IMHO this shoud be the "optimal solution" but I
    think it's a lot of work

    Thanks

    Phil
    Philipp Kraus, Feb 28, 2013
    #11
  12. Philipp Kraus <> writes:
    [...]
    > But in this way on each apply the depth counter will be increment, or
    > does it? So $depth stores not the recursion depth of item but rather
    > the depth of the apply calls, do I understand it correct?


    I'm not sure I understand correctly. On this fragment:

    <item>
    <item>...</item>
    <item>...</item>
    </item>

    You'll get 0, 1, 1.

    I now realize that maybe you want 0,1,2 (or 1,2,3). If that is the case,
    sorry, I was misled by your use of the term "recursive calls". You want
    the number of past calls, right? Can you give us a short example,
    please?

    If you want sequential numbering in document order, you can use
    select="count(preceding::item)" (or whatever you node types are).

    If you sort adjacent <item> during traversal, it gets more complex
    because you can't rely on document order. In this case I would suggest
    to first traverse your structure to generate a table associating numbers
    to nodes inside a result tree fragment, use exslt:document() to get a
    usable form of the table, and then retraverse the document to output the
    result.

    -- Alain.
    Alain Ketterlin, Feb 28, 2013
    #12
  13. On 2013-02-28 09:47:18 +0100, Alain Ketterlin said:

    > Philipp Kraus <> writes:
    > [...]
    >> But in this way on each apply the depth counter will be increment, or
    >> does it? So $depth stores not the recursion depth of item but rather
    >> the depth of the apply calls, do I understand it correct?

    >
    > I'm not sure I understand correctly. On this fragment:
    >
    > <item>
    > <item>...</item>
    > <item>...</item>
    > </item>
    >
    > You'll get 0, 1, 1.
    >
    > I now realize that maybe you want 0,1,2 (or 1,2,3). If that is the case,
    > sorry, I was misled by your use of the term "recursive calls". You want
    > the number of past calls, right? Can you give us a short example,
    > please?


    You're right, but I show you an example

    I have got a XML tree like
    <component>
    <subcomponent>
    <subsubcomponent>
    </subcomponent>

    <componentdef>
    <subcomponent>
    ....
    </.>
    </.>
    </.>


    my XSL will first match the component, so that I can create the first
    section header
    #
    the next it will match the subcomponent twice
    ##
    ##

    But the exact matches are in real depend on different if-else / choose
    structures, so
    that I have eg
    <xsl:template match="subcomponent">
    <xsl:if text="...">
    <xsl:call-template name="header">
    ...
    </xsl:call-template>
    </xsl:if>
    </xsl:template>

    So not every match creates a header in the output (here I create
    plain-text output),
    eg I can have also

    <xsl:template match="something-else">
    <xsl:choose>
    <xsl:when test="first">
    <xsl:call-template name="header">
    ...
    </xsl:call-template>
    </xsl:when>
    <xsl:when test="second"
    do something without header
    </xsl:when>
    <xsl:when test="third">
    do something
    <xsl:call-template name="header">
    ...
    </xsl:call-template>
    </xsl:when>
    </xsl:choose>
    </xsl:template>

    All templates matches, that creates a headline call one central template
    <xsl:template name="header">
    <xsl:param name="value" required="yes"/>

    <xsl:for-each select="1 to $indent">
    <xsl:call-template name="head"/>
    </xsl:for-each>

    <xsl:text> </xsl:text>
    <xsl:value-of select="$value"/>
    <xsl:call-template name="nl"/>
    </xsl:template>

    so my problem is, that I need a value for the $indent variable, that I can
    create the correct number of header indents ($value is the header title).

    So I need the recursion depth of my header template, that depends on
    various call on the input XML tree. The header calls are on different
    position in the XSL, that analyses the XML tree.
    So the efficient way is, that my header template can detect how often it is
    called recursiv.


    > If you sort adjacent <item> during traversal, it gets more complex
    > because you can't rely on document order. In this case I would suggest
    > to first traverse your structure to generate a table associating numbers
    > to nodes inside a result tree fragment, use exslt:document() to get a
    > usable form of the table, and then retraverse the document to output the
    > result.


    That's new for me, I can traversel first over my XML tree, create a table with
    data and after that the normal XSL traversel starts, so that I can read data
    from the table? Do you have an example or a link?

    In my case I would traversel the XML nodes, catch the depth of my headers
    and will set the $indent var in the second run from the table.

    Thanks a lot

    Phil
    Philipp Kraus, Feb 28, 2013
    #13
  14. Philipp Kraus <> writes:

    [...]
    >> If you sort adjacent <item> during traversal, it gets more complex
    >> because you can't rely on document order. In this case I would suggest
    >> to first traverse your structure to generate a table associating numbers
    >> to nodes inside a result tree fragment, use exslt:document() to get a
    >> usable form of the table, and then retraverse the document to output the
    >> result.

    >
    > That's new for me, I can traversel first over my XML tree, create a
    > table with data and after that the normal XSL traversel starts, so
    > that I can read data from the table?


    Yes. Table is an inadequate word, sorry, actually you can produce an
    intermediate document, that you then process in a second phase.
    Conceptually it is equivalent to have two transformations in sequence,
    the second one operating on the result of the first one.

    I was mentioning exsl:document(), this was completely wrong, I meant
    exsl:node-set() (a more or less standard extension function for XSLT1)
    but if you use XSLT2 it looks like this has been integrated (search for
    "temporary tree" in the XSLT2 recomm).

    > Do you have an example or a link?


    The relevant section of XSLT2 rec. is
    http://www.w3.org/TR/xslt20/#temporary-trees
    It looks like this replaces the "result-tree-fragment" thing of XSLT1.
    This section has en example, whose relevant part is:

    <xsl:variable name="intermediate">
    <xsl:apply-templates select="/" mode="phase1"/>
    </xsl:variable>

    <xsl:template match="/">
    <xsl:apply-templates select="$intermediate" mode="phase2"/>
    </xsl:template>

    i.e., you put the result of the first traversal in a variable, and then
    you launch the second traversal on the contents of this variable
    (instead of on some part of the original document).

    If you're stuck with XSLT1, you can use exsl:node-set() instead

    <xsl:template match="/">
    <xsl:apply-templates select="exsl:node-set($intermediate)" mode="phase2"/>
    </xsl:template>

    > In my case I would traversel the XML nodes, catch the depth of my
    > headers and will set the $indent var in the second run from the table.


    Yes, probably.

    -- Alain.
    Alain Ketterlin, Feb 28, 2013
    #14
  15. On 2013-02-28 15:35:25 +0100, Alain Ketterlin said:

    [..]

    > The relevant section of XSLT2 rec. is
    > http://www.w3.org/TR/xslt20/#temporary-trees
    > It looks like this replaces the "result-tree-fragment" thing of XSLT1.
    > This section has en example, whose relevant part is:
    >
    > <xsl:variable name="intermediate">
    > <xsl:apply-templates select="/" mode="phase1"/>
    > </xsl:variable>
    >
    > <xsl:template match="/">
    > <xsl:apply-templates select="$intermediate" mode="phase2"/>
    > </xsl:template>


    I have got only XSL 2 documents. You differ with the mode attribute the two
    traverls. How can I tell the XSL processor, that it should start with phase1,
    IMHO the position of my first match is the correct definition, or does it?

    Do I need a duplicated rule set? I have got a lot of matches without a mode
    attribute, so IMHO I need only the "phase1" mode and must assure that is run
    first, after that I can use my normal nodes and get the data from the variable.
    So how can I tell the processor, that it run the phase1 first and do
    the non-phase1
    nodes?

    Thanks for your great information and discussion, there are many new
    informations,
    to understand XSLT better

    Phil
    Philipp Kraus, Feb 28, 2013
    #15
  16. On 2/27/2013 10:29 PM, Philipp Kraus wrote:
    > Do you know another possibility without parameter


    Not in XSLT. Because XSLT may execute out of order, stateful extension
    functions wouldn't do it -- unless you passed parameters to set up data
    dependencies to control the order, in which case you might as well just
    use the params.

    Of course you could step outside XSLT entirely and handcode XML processing.

    The right answer may be to ask why you think you need this
    recursion-depth value at all, and whether you can restructure the
    problem to avoid it.

    --
    Joe Kesselman,
    http://www.love-song-productions.com/people/keshlam/index.html

    {} ASCII Ribbon Campaign | "may'ron DaroQbe'chugh vaj bIrIQbej" --
    /\ Stamp out HTML mail! | "Put down the squeezebox & nobody gets hurt."
    Joe Kesselman, Feb 28, 2013
    #16
  17. Philipp Kraus <> writes:

    [...]
    >> <xsl:variable name="intermediate">
    >> <xsl:apply-templates select="/" mode="phase1"/>
    >> </xsl:variable>
    >>
    >> <xsl:template match="/">
    >> <xsl:apply-templates select="$intermediate" mode="phase2"/>
    >> </xsl:template>

    >
    > I have got only XSL 2 documents. You differ with the mode attribute the two
    > traverls. How can I tell the XSL processor, that it should start with phase1,
    > IMHO the position of my first match is the correct definition, or does it?
    >
    > Do I need a duplicated rule set?


    Yes.

    > I have got a lot of matches without a mode attribute, so IMHO I need
    > only the "phase1" mode and must assure that is run first, after that I
    > can use my normal nodes and get the data from the variable. So how can
    > I tell the processor, that it run the phase1 first and do the
    > non-phase1 nodes?


    phase1 will run first, you can simply remove mode="phase2" in
    <xsl:apply-templates> to have the default-mode templates apply.

    Note that the variable is global in the example, but that's an artefact
    of the example. You could have:

    <xsl:template match="topmost-element-of-interest">
    <xsl:variable name="intermediate">
    <xsl:apply-templates select="." mode="phase1"/>
    </xsl:variable>
    ... do whatever is needed on the elements, using $intermediate ...
    </xsl:template>

    The variable is a node-set, you can apply-templates to it, pass it as
    parameter, etc. The elements it contains can follow any structure that
    is convenient for its later usage.

    -- Alain.
    Alain Ketterlin, Feb 28, 2013
    #17
  18. On 2013-02-28 04:09:54 +0100, Joe Kesselman said:

    > On 2/27/2013 8:14 PM, Philipp Kraus wrote:
    >> If I understand it correct, this value returns the depth of the "node
    >> recursion of my XML tree".
    >> In my problem, I want to count the recursiv call of a single template

    >
    > That was my understanding, which is why I pointed you to parameters.
    >
    > Many "counting" tasks in XSLT really are better handled by using the
    > numbering facilities designed into the language -- but those are
    > generally focused on enumerating positions in the document tree rather
    > than call depth, so they wouldn't have been the right answer for the
    > question you asked.


    Thank you too all helping people. I have start to restructer my calling
    XSL, so that I can pass a parameter from the apply rules to
    the name templates.

    Phil
    Philipp Kraus, Mar 1, 2013
    #18
  19. On 2013-02-28 19:35:43 +0100, Alain Ketterlin said:

    > Philipp Kraus <> writes:
    >
    > [...]
    >>> <xsl:variable name="intermediate">
    >>> <xsl:apply-templates select="/" mode="phase1"/>
    >>> </xsl:variable>
    >>>
    >>> <xsl:template match="/">
    >>> <xsl:apply-templates select="$intermediate" mode="phase2"/>
    >>> </xsl:template>

    >>
    >> I have got only XSL 2 documents. You differ with the mode attribute the two
    >> traverls. How can I tell the XSL processor, that it should start with phase1,
    >> IMHO the position of my first match is the correct definition, or does it?
    >>
    >> Do I need a duplicated rule set?

    >
    > Yes.
    >
    >> I have got a lot of matches without a mode attribute, so IMHO I need
    >> only the "phase1" mode and must assure that is run first, after that I
    >> can use my normal nodes and get the data from the variable. So how can
    >> I tell the processor, that it run the phase1 first and do the
    >> non-phase1 nodes?

    >
    > phase1 will run first, you can simply remove mode="phase2" in
    > <xsl:apply-templates> to have the default-mode templates apply.
    >
    > Note that the variable is global in the example, but that's an artefact
    > of the example. You could have:
    >
    > <xsl:template match="topmost-element-of-interest">
    > <xsl:variable name="intermediate">
    > <xsl:apply-templates select="." mode="phase1"/>
    > </xsl:variable>
    > ... do whatever is needed on the elements, using $intermediate ...
    > </xsl:template>
    >
    > The variable is a node-set, you can apply-templates to it, pass it as
    > parameter, etc. The elements it contains can follow any structure that
    > is convenient for its later usage.


    Thanks for your great explanation, I have started to restructure the XSL for
    using parameter, but this information is very exciting

    Phil
    Philipp Kraus, Mar 1, 2013
    #19
    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. RA Scheltema
    Replies:
    3
    Views:
    374
    RA Scheltema
    Jan 6, 2004
  2. Marijn
    Replies:
    5
    Views:
    431
    Marijn
    Feb 13, 2004
  3. Replies:
    0
    Views:
    2,206
  4. Amadeus W. M.
    Replies:
    2
    Views:
    379
    Amadeus W. M.
    Jul 4, 2006
  5. Replies:
    1
    Views:
    288
Loading...

Share This Page