XSLT 1.0成语三元如果?

时间:2012-01-12 10:06:25

标签: xslt xpath boolean ternary

这个Java程序使用三元if来将布尔值映射到输出字符串:(“*”表示true,空字符串表示false)。

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

因此输出为*,[empty],*。

我有一个输入XML文档,如:

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

我有以下XSLT模板,它将true映射为'*',将false映射为''(它可以工作):

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

是否有更简洁的版本?

a)我可以直接从字符串'true | false'自动获取布尔值true | false的值吗? b)是否有(xpath?)构造将布尔值true | false映射到'*',''?

2 个答案:

答案 0 :(得分:8)

  

a)我可以直接从中自动获取布尔值true | false的值   字符串'true | false'?

     

b)是否有(xpath?)构造将布尔值true | false映射到   '*',''?

这实际上是一个XPath问题

<强>予。 XPath 1.0

有多个XPath表达式,其评估产生想要的结果:

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

这也回答b) - 注意字符串 'true''false'不是布尔值!只有两个布尔值是true()false(),它们不是字符串。

在上面的表达式中,我们使用的事实是,在XPath 1.0中,如果布尔值位于需要数字的上下文中,则会自动转换为数字。根据定义:

number(true())1

number(false())0

因此上面调用substring()的第二个参数:

2 - (@flag = 'true')

1时评估为@flag = 'true',否则评估为2

更通用的XPath 1.0表达式,如果$s1$val则生成字符串"x",如果$s2$val则生成字符串"y" {1}}

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

这会在$s1时生成字符串$val = "x",在$s2时生成字符串$val = "y",如果这两个条件都不成立,则生成空字符串。

上面的XPath 1.0表达式可以推广,以便在$s1是其中一个值时生成N个不同的字符串结果$2$sN,...,$val $v1$v2,...,$vN,因为函数concat()可以包含任意数量的参数。


<强> II。 XPath 2.0(XSLT 2.0)

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

更一般地说,给定2 * N原子值$s1$s2,... $sN$v1$v2,..., $vN,这样所有$vi值都不同,这是评估此XPath 2.0表达式的结果:

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

$v eq $vK

答案 1 :(得分:1)

您可以在模板中使用简单的模式匹配。

<xsl:template match="change[@flag = 'true']">

<xsl:template match="change">

因此,第一个匹配 true 条目,另一个匹配所有其他情况(在您的情况下只是 false

因此,给出以下样式表

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="text" indent="yes"/>

   <xsl:template match="change[@flag = 'true']">
      <xsl:text>*&#13;</xsl:text>
   </xsl:template>

   <xsl:template match="change">
      <xsl:text>&#13;</xsl:text>
   </xsl:template>

   <xsl:template match="@*|node()">
      <xsl:apply-templates select="@*|node()"/>
   </xsl:template>
</xsl:stylesheet>

当应用于您的示例XML时,输出以下内容

*

*