【问题标题】:How to control boolean rendering in xslt如何在 xslt 中控制布尔渲染
【发布时间】:2011-10-28 17:12:19
【问题描述】:

为了符合<boolean> spec of Xml-RPC 我需要将我的xs:booleantrue|false 转换为1|0

我使用 xsl:choose 解决了这个问题

<xsl:template match="Foo">
    <member>
        <name>Baz</name>
        <value>
            <boolean>
                <xsl:choose>
                    <xsl:when test=".='true'">1</xsl:when>
                    <xsl:otherwise>0</xsl:otherwise>
                </xsl:choose>
            </boolean>
        </value>
    </member>
</xsl:template>

但想知道在使用 xslt 1.0 转换时是否有一种更简单的方法来控制布尔值的呈现方式。

【问题讨论】:

  • 好问题,+1。请参阅我的答案以获得完整、简短且简单的解决方案(XPath 单行)。 :)

标签: xslt casting boolean xml-rpc


【解决方案1】:

使用

number(boolean(.))

根据标准 XPath 函数 number() 的定义,当分别在 {true(), false()} 上应用时,它会准确生成 {0, 1}

当心!如果你在 strings 上使用这种结构,结果将 'false' 和 'true' 都为 true,因为,对于字符串参数,boolean() is true if and only if its length is non-zero

所以,如果你想转换字符串,而不是布尔值,那么使用这个表达式:

number(not(. = 'false'))

以下是基于 XSLT 的验证

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match="text()">
  <xsl:value-of select="number(not(. = 'false'))"/>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于以下 XML 文档时

<t>
 <x>true</x>
 <y>false</y>
</t>

产生想要的正确结果

<t>
   <x>1</x>
   <y>0</y>
</t>

【讨论】:

  • 优秀的 als 总是 - 但我喜欢的版本 number(boolean(.)) 似乎不起作用......它总是返回 1。我将进行字符串比较,这将允许我在我的解决方案中使用更通用的模板。
  • 似乎number(boolean('false')) 将返回1number(boolean(false)) 将返回0 所以最终幸福的剩余问题是如何检索xs:boolean 元素的非文字值; -)
  • @Filburt:如果你真的有一个布尔值,那么使用:number(.)。仍然存在问题的原因是您没有提供完整的 XML 文档和想要的完整结果。当人们猜测这些时,即使是 10% 的成功率也是巨大的。
  • 我承认,如果我不给出一个完整的例子(包括源和期望的结果),我可以拥有一切,但我确实明确指出我的源值类型是 xs:boolean ...我注意到我的帖子中有一个错字:xsl:boolean 并不是真正的类型。在发布我的问题之前我确实进行了挖掘并尝试了number(.),它产生了NaN。无论如何,你给了 100%,我不想显得忘恩负义地问为什么 xslt 1.0 不允许 150% ;-)
  • XSLT 1.0/XPath 1.0 不是强类型的,大多数情况下的大多数值都是字符串类型(可以转换为其他类型)。而且,不幸的是,boolean(string(false()))true()——不是假的。因此,必须使用number(not(. = 'false')){'true', 'false'} 转换为{1, 0}
猜你喜欢
  • 2013-10-04
  • 1970-01-01
  • 1970-01-01
  • 2020-05-08
  • 2014-05-23
  • 1970-01-01
  • 2014-11-02
  • 2016-11-09
  • 1970-01-01
相关资源
最近更新 更多