Nelson Katende
Nelson Katende

Reputation: 31

XSL how do i test a boolean data type?

I am trying to test an attribute which is defined in the schema as a Boolean data type. The XML is dynamically created and if the value in the XML is 1, I simply want to print something. But nothing is printing.

Here is the schema

<xs:element name="Data">
                    <xs:complexType>
                      <xs:all minOccurs="1" maxOccurs="1"> 
                        <xs:element id="variable" name="variable" type="xs:boolean" />
                      </xs:all>
                    </xs:complexType>
                  </xs:element>

Here is the XML

<Data>
                    <variable>1</variable>
                    <variable2>0</variable2>
                    <variable3>1</variable3>
                  </Data>

I have tried various ways. Here is what I have tried (I tried WHEN and IF)

<xsl:choose>        
                    <xsl:when test="variable = '1'">Print something</xsl:when>
                    <xsl:when test="variable = 1">Print something</xsl:when>
                    <xsl:when test="variable = 'true'">Print something</xsl:when>
                    <xsl:when test="@variable = 1">Print something</xsl:when>
                    <xsl:when test="@variable = '1'">Print something</xsl:when>
                    <xsl:when test="@variable = true">Print something</xsl:when> 
                    <xsl:otherwise>
                      <!--nothing-->
                    </xsl:otherwise>
                </xsl:choose>

                  <xsl:if test="variable = '1'">Print something</xsl:if>
                  <xsl:if test="variable = 'true'">Print something</xsl:if>

My XSL starts with this

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"

Upvotes: 2

Views: 8929

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 117140

First thing: unless you are using a schema-aware processor, it doesn't really matter what your schema says.

Next, if you are using an XSLT 2.0 processor, as your stylesheet declares, then you can see if a value is true or false by applying the following test:

test="xs:boolean(value)"

For example, given the following test input:

XML

<Data>
    <variable>1</variable>
    <variable>0</variable>
    <variable>true</variable>
    <variable>false</variable>
</Data>

and applying the following stylesheet:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/Data">
    <result>
        <xsl:for-each select="variable">
            <xsl:copy>
                <xsl:choose>        
                    <xsl:when test="xs:boolean(.)">Print something</xsl:when>
                    <xsl:otherwise>
                        <!--nothing-->
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:copy>
        </xsl:for-each>
    </result>
</xsl:template>

</xsl:stylesheet> 

will produce the following result:

<?xml version="1.0" encoding="UTF-8"?>
<result>
   <variable>Print something</variable>
   <variable/>
   <variable>Print something</variable>
   <variable/>
</result>

which corresponds to what XML Schema defines as the allowed values for a boolean data type.


Are you really using an XSLT 2.0 processor?

I have a good reason to doubt that: your stylesheet also declares a Microsoft namespace:

xmlns:msxsl="urn:schemas-microsoft-com:xslt"

and AFAIK there are no Microsoft XSLT 2.0 processors.

To perform the same test in XSLT 1.0, you will need to do:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/Data">
    <result>
        <xsl:for-each select="variable">
            <xsl:copy>
                <xsl:choose>        
                    <xsl:when test="number(.) or .='true'">Print something</xsl:when>
                    <xsl:otherwise>
                        <!--nothing-->
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:copy>
        </xsl:for-each>
    </result>
</xsl:template>

</xsl:stylesheet>

If you can be sure that the value of variable will always be only either 1 or 0, then you can shorten the test to:

<xsl:when test="number(.)">

Upvotes: 3

Related Questions