8

此 Java 程序使用三元 if 将布尔值映射到输出字符串:(“*”表示真,空字符串表示假)。

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

所以输出是*,[空],*。

我有一个输入 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 映射到 '*', '' ?

4

2 回答 2

8

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

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

这实际上是一个 XPath 问题

一、XPath 1.0

有不止一个 XPath 表达式的求值产生想要的结果:

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

这也回答了 b) - 注意字符串 'true''false'不是布尔值!仅有的两个布尔值是true()andfalse()并且它们不是字符串。

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

number(true())1

number(false())0

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

2 - (@flag = 'true')

被评估为何1@flag = 'true'2否则。

一个更通用的 XPath 1.0 表达式,它生成字符串$s1if $valis"x"并生成字符串$s2if $valis"y"

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

这将产生字符串$s1when $val = "x"、字符串$s2when$val = "y"和空字符串——如果这两个条件都不成立。

上面的 XPath 1.0 表达式可以概括为产生 N 个不同的字符串结果$s1, $2, ...,$sN确切地说是什么时候$val是值$v1, $v2, ... 之一,$vN 因为该函数concat()可以有任意数量的参数。


二、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

于 2012-01-12T13:35:44.710 回答
1

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

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

<xsl:template match="change">

所以,第一个匹配真正的条目,另一个匹配所有其他情况(在你的情况下只是

因此,给定以下样式表

<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 时,将输出以下内容

*

*
于 2012-01-12T10:20:54.000 回答