20

I am creating XSLT file. I have one variable which take value from XML file.But it may happen that there is no reference in xml for the value and at that time XSL variable will return False/None(don't know).I want keep condition like,If there is no value for the variable use the default one. How to do that ?

DSS
  • 201
  • 1
  • 2
  • 3
  • possible duplicate of [In XSLT how do you test to see if a variable exists?](http://stackoverflow.com/questions/1299808/in-xslt-how-do-you-test-to-see-if-a-variable-exists) – Chris Page Feb 23 '14 at 02:22

5 Answers5

33

With the few details given in the question, the simplest test you can do is:

<xsl:if test="$var">
    ...
</xsl:if>

Or you might use xsl:choose if you want to provide output for the else-case:

<xsl:choose>
    <xsl:when test="not($var)"> <!-- parameter has not been supplied -->
</xsl:when>
    <xsl:otherwise> <!--parameter has been supplied --> </xsl:otherwise>
</xsl:choose>

The second example will also handle the case correctly that the variable or parameter has not been supplied with an actual value, i.e. it equals the empty string. This works because not('') returns true.

Dirk Vollmar
  • 172,527
  • 53
  • 255
  • 316
  • 4
    although you might fine `test="$var != ''"` a bit better if testing for variable content vs. existence. – scunliffe Nov 18 '10 at 19:50
  • 1
    I second @scunliffe - if $var exists but is empty, `test="$var"` will still return true. However, you may need to write it `test="not($var = '')"` if you are using earlier versions of XSL. – Scott Baker Nov 18 '10 at 19:54
  • @scunliffe: See my extended answer for handling empty strings. – Dirk Vollmar Nov 18 '10 at 19:54
  • @0xA3: You wrote: *also handle the case correctly that the variable has not been set at all*. There is no such thing in XSLT language. Variables are always "set". Check my answer. –  Nov 18 '10 at 20:05
  • @Alejandro: My wording was not precise, but it is possible not to explicitly select a value for a variable/parameter in which case the variable will take an empty string as the default value. – Dirk Vollmar Nov 18 '10 at 20:25
  • @0xA3: Parameters are other thing at all. So much that the default value problem should be treated in other way. –  Nov 18 '10 at 20:28
16

You haven't explained what you mean by "has no value". Here is a generic solution:

not($v) and not(string($v))

This expression evaluates to true() iff $v "has no value".

Both conditions need to be met, because a string $v defined as '0' has a value, but not($v) is true().

In XSLT 1.0 using a default can be achieved in different ways if the "value" is a node-set or if the value is a scalar (such as a string, a number or a boolean).

@Alejandro provided one way to get a default value if a variable that is supposed to contain a node-set is empty.

If the variable is supposed to contain a scalar, then the following expression returns its value (if it has a value) or (otherwise) the desired default:

concat($v, substring($default, 1 div (not($v) and not(string($v)))))
Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
  • How can be a variable not set, even with an scalar value? Only a parameter could be not set (and without a default expression). Only in that case, the parameter would take the empty string as value. –  Nov 18 '10 at 20:53
  • @Alejandro: According to [point 11.](http://www.w3.org/TR/xslt#variables) a variable *may* be bound to a value. If there is no value explicitly provided by a select attribute or the content of the variable-binding element, the third bullet of [point 11.2](http://www.w3.org/TR/xslt#variable-values) applies binding the variable to an empty string. – Dirk Vollmar Nov 18 '10 at 20:58
  • 1
    @0xA3: No. It say that `variable-binding element can specify the value of the variable in three alternative ways`, and the third way is `variable-binding element has empty content and does not have a select attribute, then the value of the variable is an empty string`. So, it has a well defined value. There is no such thing as no value. –  Nov 18 '10 at 21:05
6

You can use string-length to check, if a variable called $reference for example contains anything.

<xsl:choose>

  <xsl:when test="string-length($reference) > 0">
    <xsl:value-of select="$reference" />
  </xsl:when>

  <xsl:otherwise>
    <xsl:text>some default value</xsl:text>
  </xsl:otherwise>

</xsl:choose>

If necessary use normalize-space, too.

ceving
  • 21,900
  • 13
  • 104
  • 178
  • Nice. Notice the normalize-space if you're checking a parameter that is inside XML. Carriage returns need to be removed. – Faliorn Aug 29 '22 at 12:08
0

I tried a lot of solution from SO, my last solution was taken from @dimitre-novatchev, but that one also not working every time. Recently I found one more solution from random google search, thought to share with the community.

In order to check empty variable value, we can declare an empty variable and compare its value against test condition. Here is code snippet:

<xsl:variable name="empty_string"/>
<xsl:if test="testVariableValue != $empty_string">
...
</xsl:if>

Here testVariableValue hold the value of new variable to be tested for empty scenario. Hope it would help to test empty variable state.

Sudip7
  • 2,384
  • 3
  • 27
  • 35
0

First, all variables has values, because XSLT belongs to declarative paradigm: there is no asignation instruction, but when you declare the variable you are also declaring the expression for its value relationship.

If this value it's a node set data type (that looks from your question), then you should test for an empty node set in case nothing was selected. The efective boolean value for an empty node set is false. So, as @0xA3 has answered: test="$node-set".

You wrote:

If there is no value for the variable use the default one. How to do that ?

Well, that depends on what kind of data type you are looking for.

Suppose the node set data type: if you want $node-set-1 value or $node-set-2 if $node-set-1 is empty, then use:

$node-set-1|$node-set-2[not($node-set-1)]
Community
  • 1
  • 1
  • @Alejandro: This is a good answer, but the OP hasn't indicated anywhere that the value is to hold a node-set. It may be just a string... – Dimitre Novatchev Nov 18 '10 at 20:28
  • @Dimitre: Good point. I read this sentence in that way: `I have one variable which take value from XML file`. –  Nov 18 '10 at 20:41