tags:

views:

76

answers:

2

I am using an XSLT where I have created <xsl:template> tag which does some validation using an <xsl:for-each> statement and sets the value of <xsl:variable> or <xsl:param> to true or false.

  1. Is there any way to break the statement in for-each if condition is true?
  2. Can we use the value of Template variable or param from main calling routine?

Example:

<!-- Main Xslt -->
<xsl:template>
  <xsl:call-template name ="TestTemplate">
    <!--  
      Here I want to use the variable or param that 
      is defined in TestTemplate, is it possible?
    -->
  </xsl:call-template>
</xsl:template>

<xsl:template name ="TestTemplate">
  <xsl:param name="eee"/>
  <xsl:for-each select ="//RootNode/LeafNode">
    <xsl:choose>
      <xsl:when test ="@Type='ABC'">
        <xsl:value-of select ="true"/>
      </xsl:when>
      <xsl:otherwise>false</xsl:otherwise>
    </xsl:choose>
  </xsl:for-each>
</xsl:template>
A: 

ad 1. I think that it is not possible but I am not sure

ad 2. Yes, you can use parameter but pay attention on it because it is constant. All variables and parameters in XSL are constants. Look at W3School - variable

cite:

Once you have set a variable's value, you cannot change or modify that value!

The same thing is for parameters.

You can call template with ( constant ) parameter:

<call-template name="myTemplate">
   <xsl:with-param name="name" select="expression">
</call-template>

Look at W3School - with parameter it is really good reference page.

Gaim
+2  A: 

To your questions:

Is there any way to break the statement in for-each if condition is true ?

No, and normally this is also unnecessary. XSLT is not an imperative programming language, and imperative approaches do not really work well here.

What you seemingly want to do is expressing "find the first <LeafNode> where @Type='ABC', and return true or false depending on whether there is one.

The way to do this in traditional languages is like your approach: for each node, check condition, if condition satisfied then return.

In XSLT you simply select the node with XPath:

//RootNode/LeafNode[@Type='ABC']

either the result of this contains a node, or it does not. No need for a for-each at all.

Can we use the value of Template variable or param from main calling routine ?

No. Variables and params are strictly scoped. They go out of scope once processing leaves their parent element. They are also constant, once declared they cannot be changed.

The way to do what you want here is making the template output the desired value and capture it in a variable:

<xsl:template>
  <xsl:variable name="returnValue">
    <xsl:call-template name="TestTemplate" />
  </xsl:variable>
</xsl:template>

<xsl:template name="TestTemplate">
  <!-- the following expression emits true or false -->
  <xsl:value-of select="
    count(//RootNode/LeafNode[@Type='ABC']) gt; 0
  " />
</xsl:template>

Two last hints:

  • avoid the '//' operator at all costs. Most of the time its use is not necessary
  • the first, top-most element in a document is not the "root node", it is the "document element"

This is an important distinction. The "root node" comes before the document element, so the XPath above should be more like this (semantically):

/DocumentElement/LeafNode
^------ *this* slash represents the "root node"
Tomalak