Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XSLT 1.0 Idiom for ternary if?

This Java program makes use of a Ternary if, to map booleans to output strings: (a "*" for true, an empty string for false).

public class ternary {
  public static void main(String[] args) {
    boolean flags[]={true,false,true};
    for (boolean f : flags) {
      System.out.println(f?"*":"");
    }
  }
}

So the output is *, [empty], *.

I have an input XML document, something like:

<?xml version="1.0" ?>
<?xml-stylesheet type="text/xsl" href="change.xsl"?>
<root>
  <change flag="true"/>
  <change flag="false"/>
  <change flag="true"/>
</root>

And I have the following XSLT template which maps true to '*' and false to '' (it works):

<xsl:template match="change">
  <xsl:variable name="flag" select="translate(substring(@flag,1,1),'tf','*')"/>
  <xsl:value-of select="$flag"/>
</xsl:template>

Is there is more concise version of this ?

a) Can I automatically get a value of boolean true|false directly from the string 'true|false' ? b) Is there an (xpath?) construct to map the boolean true|false to '*', '' ?

like image 267
monojohnny Avatar asked Jan 12 '12 10:01

monojohnny


People also ask

Can we use if condition in XPath?

An XPath expression beginning with the keyword 'if' signifies a conditional expression. if (/company/office[@location = 'Boston']/employee[1]/age = 35) then 'is 35' else 'is not 35'. The keyword 'if' is followed by a test expression in parentheses which returns a boolean value i.e. 'true' or 'false'.

What is text () in XSLT?

The <xsl:text> element is used to write literal text to the output. Tip: This element may contain literal text, entity references, and #PCDATA.

What is Number () in XSLT?

Specifies the format pattern. Here are some of the characters used in the formatting pattern: 0 (Digit)

What is specify condition in XSLT?

The XSLT <xsl:if> element is used to specify a conditional test against the content of the XML file.


1 Answers

a) Can I automatically get a value of boolean true|false directly from the string 'true|false' ?

b) Is there an (xpath?) construct to map the boolean true|false to '*', '' ?

This is actually an XPath question.

I. XPath 1.0

There are more than one XPath expressions the evaluation of which produces the wanted result:

substring('*', 2 -(@flag = 'true'))

This also answers b) -- notice that the strings 'true' and 'false' aren't boolean values! The only two boolean values are true() and false() and they are not strings.

In the above expression we use the fact that in XPath 1.0 if a boolean is in a context where a number is needed, it is automatically converted to number. By definition:

number(true()) is 1

and

number(false()) is 0

Thus the second argument of the call to substring() above:

2 - (@flag = 'true')

is evaluated as 1 when @flag = 'true' and to 2 otherwise.

A more general XPath 1.0 expression that produces the string $s1 if $val is "x" and produces the string $s2 if $val is "y" :

concat(substring($s1, 1 div ($val = "x")),
       substring($s2, 1 div ($val = "y"))
      )

This produces the string $s1 when $val = "x", the string $s2 when $val = "y", and the empty string -- if none of these two conditions holds.

The above XPath 1.0 expression can be generalized to produce N different string results $s1, $2, ..., $sN exactly when $val is one of the values $v1, $v2, ..., $vN because the function concat() can have any number of arguments.


II. XPath 2.0 (XSLT 2.0)

'*'[current()/@flag = 'true']

And more generally, given 2*N atomic values $s1, $s2, ... $sN and $v1, $v2, ..., $vN, such that all $vi values are different, the result of evaluating this XPath 2.0 expression:

 ($s1, $s2, ..., $sN)[index-of(($v1, $v2, ..., $vN), $v)]

is $sK exactly when $v eq $vK.

like image 181
Dimitre Novatchev Avatar answered Sep 20 '22 13:09

Dimitre Novatchev