比较XSLT中的xs:boolean值?

时间:2010-11-20 17:03:28

标签: xslt boolean

我有一个xml架构,其元素定义为类型xs:boolean,如下所示:

<xs:element name="useful"
              minOccurs="1" maxOccurs="1"
              type="xs:boolean"/>

我正在尝试使用XSL中的choose / when / otherwise块来输出基于其值的特定内容,如下所示:

<xsl:choose>
   <xsl:when test="@useful = 0">No</xsl:when>
   <xsl:otherwise>Yes</xsl:otherwise>
</xsl:choose>

我已经尝试了我能想到的每个变体用于比较(使用true(),false(),1,0,删除@,使用// @)并且它总是打印出“是”。我在这里做错了什么?

编辑(应Martin Honnen的要求):

以下是正在使用的XML示例:

<?xml version="1.0"?>
<functions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:noNamespaceSchemaLocation="functions.xsd">
   <function>
      <name>func1</name>
      <useful>0</useful>
   </function>

   <function>
      <name>func2</name>
      <useful>1</useful>
   </function>
</functions>

这会导致使用xsl:template的问题我认为,所以我使用xsl:for-each循环遍历每个函数,并尝试输出特定于每个有用标记的内容。 xsl:template只能在xslt的顶层使用,对吗?

完整的XSLT文件是

<?xml version='1.0' ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="/">
      <html><body>
         <h2>Functions</h2>
            <table border="1">
              <tr>
                  <th>Functions</th>
                  <th>Useful</th>
               </tr>
               <xsl:for-each select="functions/function">
                  <tr>
                     <td>
                        <xsl:value-of select="name"/>
                     </td>
                     <td>
                        <xsl:choose>
                           <xsl:when test="@useful = 0">No</xsl:when>
                           <xsl:otherwise>Yes</xsl:otherwise>
                        </xsl:choose>
                     </td>
                  </tr>
               </xsl:for-each>
            </table>
         </body></html>
      </xsl:template>
</xsl:stylesheet>

2 个答案:

答案 0 :(得分:3)

我认为架构定义了一个元素,但是你正在测试一个属性的值 - 这可能是你的主要问题。

<xsl:choose> 
   <xsl:when test="@useful = 0">No</xsl:when> 
   <xsl:otherwise>Yes</xsl:otherwise> 
</xsl:choose> 
  

我已经尝试过我能想到的每一种变化   对于那种比较(使用   true()false()10,   删除@,使用//@)和它   总是打印出“是”。我是什么   在这里做错了吗?

最有可能当前节点不是具有名为useful的属性的元素。

以下是如何使用模式定义的useful元素类型在XSLT 1.0中工作:

<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="useful/text()[. = 'true' or .='1']">
  Yes
 </xsl:template>

 <xsl:template match="useful/text()[. = 'false' or .='0']">
  No
 </xsl:template>
</xsl:stylesheet>

将此转换应用于以下XML文档

<t>
    <useful>true</useful>
    <useful>false</useful>
    <useful>1</useful>
    <useful>0</useful>
</t>

产生了想要的正确结果

<t>
    <useful>
  Yes
 </useful>
    <useful>
  No
 </useful>
    <useful>
  Yes
 </useful>
    <useful>
  No
 </useful>
</t>

在XSLT 2.0(架构感知处理器)中,您需要导入架构(使用<xsl:import-schema>),然后您只需使用:

('no', 'yes')[number(useful)+1]

其中当前节点是useful元素的父节点。

答案 1 :(得分:1)

您的架构定义了一个名为“有用”的元素,但除非您尝试使用架构感知XSLT 2.0,否则架​​构根本不相关。

在XPath中执行@useful选择上下文节点名称的属性,该属性与您拥有的模式没有任何关系,因为它定义了一个元素。 因此,向我们展示XSLT正在处理的实例XML,然后我们可以向您展示一些XSLT代码:

<xsl:template match="useful">
  <xsl:choose>
    <xsl:when test=". = 'false' or . = 0">No</xsl:when>
    <xsl:otherwise>Yes</xsl:otherwise>
  </xsl:choose>
</xsl:template>

使用模式感知XSLT 2.0,你可以做到

<xsl:template match="useful">
  <xsl:value-of select="if (data(.)) then 'Yes' else 'No'"/>
</xsl:template>