Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 201015
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 11, 20262026-05-11T17:09:44+00:00 2026-05-11T17:09:44+00:00

I am processing an XML file where I want to keep count of the

  • 0

I am processing an XML file where I want to keep count of the number of nodes, so that I can use it as an ID as I write new nodes.

At the moment I have a global variable called ‘counter’. I am able to access it within a template, but I haven’t found a way of manipulating it within a template.

Here is a condensed version of my XSLT file:

<xsl:variable name="counter" select="1" as="xs:integer"/>

<xsl:template match="/"> 
   <xsl:for-each select="section">
      <xsl:call-template name="section"></xsl:call-template>
   </xsl:for-each>
</xsl:template>

<xsl:template name="section">

   <!-- Increment 'counter' here -->

   <span class="title" id="title-{$counter}"><xsl:value-of select="title"/></span>
</xsl:template>

Any suggestions how to go from here?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-11T17:09:44+00:00Added an answer on May 11, 2026 at 5:09 pm

    Others have already explained how variables are immutable–that there are no assignment statements in XSLT (as with purely functional programming languages in general).

    I have an alternative to the solutions that have been proposed so far. It avoids parameter passing (which is verbose and ugly in XSLT–even I’ll admit that).

    In XPath, you can simply count the number of <section> elements that precede the current one:

    <xsl:template name="section">
      <span class="title" id="title-{1 + count(preceding-sibling::section)}">
        <xsl:value-of select="title"/>
      </span>
    </xsl:template>
    

    (Note: the whitespace code formatting won’t appear in your result, as whitespace-only text nodes get stripped from the stylesheet automatically. So don’t feel compelled to put instructions on the same line.)

    One big advantage of this approach (as opposed to using position()) is that it’s only dependent on the current node, not on the current node list. If you changed your processing somehow (e.g., so <xsl:for-each> processed not only sections but some other element too), then the value of position() would no longer necessarily correspond to the position of <section> elements in your document. On the other hand, if you use count() as above, then it will always correspond to the position of each <section> element. This approach reduces coupling with other parts of your code, which is generally a very good thing.

    An alternative to count() would be to use the <xsl:number> instruction. It’s default behavior will number all like-named elements at the same level, which happens to be what you want:

    <xsl:template name="section">
      <xsl:variable name="count">
        <xsl:number/>
      </xsl:variable>
      <span class="title" id="title-{$count}">
        <xsl:value-of select="title"/>
      </span>
    </xsl:template>
    

    It’s a trade-off in verbosity (requiring an additional variable declaration if you still want to use the attribute value template curly braces), but only slightly so, as it also drastically simplifies your XPath expression.

    There’s yet more room for improvement. While we’ve removed dependency on the current node list, we still are dependent on the current node. That, in and of itself, is not a bad thing, but it’s not immediately clear from looking at the template what the current node is. All we know is that the template is named “section“; to know for sure what’s being processed, we have to look elsewhere in our code. But even that doesn’t have to be the case.

    If you ever feel led to use <xsl:for-each> and <xsl:call-template> together (as in your example), step back and figure out how to use <xsl:apply-templates> instead.

    <xsl:template match="/doc">
      <xsl:apply-templates select="section"/>
    </xsl:template>
    
    <xsl:template match="section">
      <xsl:variable name="count">
        <xsl:number/>
      </xsl:variable>
      <span class="title" id="title-{$count}">
        <xsl:value-of select="title"/>
      </span>
    </xsl:template>
    

    Not only is this approach less verbose (<xsl:apply-templates/> replaces both <xsl:for-each> and <xsl:call-template/>), but it also becomes immediately clear what the current node is. All you have to do is look at the match attribute, and you instantly know that you’re processing a <section> element and that <section> elements are what you’re counting.

    For a succinct explanation of how template rules (i.e. <xsl:template> elements that have a match attribute) work, see “How XSLT Works”.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have an XML File that I am processing using LINQ. I want to
I have a file that keeps appending the following xml. What I want to
I have a situation where I have an xml file that I don't want
I have a set of XML files that I am processing with an XSL
I have a big (1.9 GB) XML file which has data I want to
I have an XML file that I am trying to search using Java. I
I want to load xml file into spring bean for further processing. I know
Is it possible to skip over nodes while processing a xml file? For example:
I have an xml file saved and this is what I want to do,
I am processing an xml file using apache.commons.digester The xml is, for instance, structured

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.