tags:

views:

875

answers:

2

I need to be able to check what the "current" value of a variable is inside a redeclaration of that same variable in a different xslt that includes the other.

main.xslt:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
    <xsl:import href="other.xslt"/>
    <xsl:variable name="email">
     <xsl:if test="string-length($email) = 0">
      [email protected]
     </xsl:if>
    </xsl:variable>
    <xsl:template match="/">
     <Email>
      <xsl:value-of select="$email"/>
     </Email>
    </xsl:template>
</xsl:stylesheet>

other.xslt:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
    <xsl:variable name="email">[email protected]</xsl:variable>
</xsl:stylesheet>

What I would like to do is be able to check what the value of the lower-precedence variable will be to see if I need to overwrite it in the variable in the current xslt. (disclaimer - the current code crashes viciously)

A: 

You can't do what you want directly, you'd have to set a second variable.

But I can't understand the intent: if this was template based you could supply a default value to any param (which act very similarly to variables). The way you phrase the question suggests that's the right approach to me, but can you clarify how these templates relate and are used?

annakata
@annakata: I think you have misunderstood the question. It makes sense while it doesn't ask how to provide a default value to a parameter of a template. See the specific code within my answer. Cheers,
Dimitre Novatchev
@Dimitre - but what you describe is exactly the second variable plan and I think it's pretty clear that the first var *is* used directly in the importer within the definition of the second, regardless of it's non-usage elsewhere. The param on a template solution is simpler and probably correct.
annakata
@annakata - I think these are two different scenarios and each has its own use. The OP, however, indicated in a comment, that what he really wanted was to default a global variable.
Dimitre Novatchev
+3  A: 

As others have noted, adding a default to a global variable that is defined in an imported stylesheet, cannot be done using the same variable name. This is because the variable with that name that is defined in the current xslt stylesheet has higher precedence than the one in the imported stylesheet and only the former will be used (you cannot access the identically named variable in the lower precedence stylesheet).

Here is how one can add a default:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
<!--                                            -->
  <xsl:import href="other.xsl"/> 
<!--                                            -->
    <xsl:variable name="vMyEmail" select=
     "concat(substring('[email protected]', 1 div not($vEmail)), $vEmail)"
     />
<!--                                            -->
    <xsl:template match="/">
      <xsl:value-of select="$vMyEmail"/>
    </xsl:template>
</xsl:stylesheet>

Do note that the global variable $vMyEmail is defined in such a way that it has the value of the variable $vEmail (defined in the imported stylesheet) if this is a string with length at least 1, or the desired default value -- otherwise.

Using this technique, one will use the so defined $vMyEmail anywhere following its definition. The $vEmail variable from the imported stylesheet will not be used directly at all.

Dimitre Novatchev
Thanks - this is the answer I was looking for.
Andrew Hare