1

I'm trying give a variable a value within XSL:for-each and access the variable after the XSL:for-loop has ended (or even after it's moved to the next XSL:for-each). I've tried using both global and local variables but they don't seem to work.

Is this possible? If not, is there another way around the problem?

-Hammer

Hammer
  • 57
  • 2
  • 2
  • 7
  • Please, provide your XML and XSLT code (minimal, please) and explain better what the problem is. Then many of the readers would be able to show you a solution. As for your general question, the answer is negative, as already explained by @Tomalak and @Mads-Hansen. – Dimitre Novatchev Oct 17 '10 at 14:53

3 Answers3

3

I'm trying give a variable a value within XSL:for-each and access the variable after the XSL:for-loop has ended (or even after it's moved to the next XSL:for-each)

No, this is not possible. There are ways around it, but which one is the best depends on what you want to do.

See this very similar question for a detailed explanation. Also read this thread, as it is closely related as well.

Community
  • 1
  • 1
Tomalak
  • 332,285
  • 67
  • 532
  • 628
1

The only way, I found is to use call-template and send as param the result of your "for-each" .

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:mvn="http://maven.apache.org/POM/4.0.0">
  <xsl:variable name="project" select="/mvn:project" />

  <xsl:template name="parseDependencies">
    <xsl:param name="profile" />
    <xsl:for-each select="$profile/mvn:dependencies/mvn:dependency">
        <dependency>
          <xsl:attribute name="profile">
            <xsl:value-of select="$profile/mvn:id" />
          </xsl:attribute>
          <xsl:for-each select="mvn:*[node()]">
            <xsl:element name="{name(.)}">
              <xsl:call-template name="parseContent">
                <xsl:with-param name="text" select="text()" />
              </xsl:call-template>
            </xsl:element>
          </xsl:for-each>
        </dependency>
    </xsl:for-each>
  </xsl:template>

  <xsl:template match="mvn:project">
      <dependencies>
        <xsl:call-template name="parseDependencies">
          <xsl:with-param name="profile" select="." />
        </xsl:call-template>
        <xsl:for-each select="mvn:profiles/mvn:profile">
          <xsl:call-template name="parseDependencies">
            <xsl:with-param name="profile" select="." />
          </xsl:call-template>
        </xsl:for-each>
      </dependencies>
  </xsl:template>
</xsl:stylesheet>

Here I call parseDependencies in maven project (pom.xml) to scan dependencies in project node and for each profile node. To register the "node" I use the parameter $profile and when I parse dependencies loop I used it to retrieve the profile "id".

NB: parseContent is not here, but it used to resolve maven parameters.

3ldryn
  • 11
  • 1
0

XSLT variables are immutable(cannot be changed) and are strictly scoped.

You can always wrap the xsl:for-each with an xsl:variable. Any text values emitted within the xsl:for-each will be assigned to the xsl:variable.

For example, the following stylesheet declares a variable textValueCSV. Within the xsl:for-each it uses xsl:value-of and xsl:text. All of the text values are assigned to the variable textValuesCSV, which is used outside of the xsl:for-each to select it's value.

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="text" />

<xsl:template match="/">

    <xsl:variable name="textValuesCSV">
        <xsl:for-each select="/*/*">
            <xsl:value-of select="."/>
            <xsl:if test="position()!=last()">
                <xsl:text>,</xsl:text>
            </xsl:if>
        </xsl:for-each>
    </xsl:variable>

    <xsl:value-of select="$textValuesCSV"/>

</xsl:template>

</xsl:stylesheet>

When applied to this XML:

<doc>
    <a>1</a>
    <b>2</b>
    <c>3</c>
</doc>

Produces this output:

1,2,3
Mads Hansen
  • 63,927
  • 12
  • 112
  • 147