RE: [xsl] Implementing a (fairly) complex business rule

Subject: RE: [xsl] Implementing a (fairly) complex business rule
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Tue, 30 Sep 2008 14:57:13 +0100
XSLT 2.0 is your friend. If you ran this in 2.0

string-length(s0:POSTCODE/text() = 0)

you would get an error message: the argument to string-length() must be a
string, not a boolean. As it is, string-length("true") is 4,
string-length("false") is 5, and both 4 and 5 convert to the boolean true
when treated as a boolean value.

Your closing paren is in the wrong place. 

Incidentally, the "/text()" scattered throughout your code is unnecessary
and in my view, bad practice. It means your code will fail if there are
comments in unexpected places in the source tree.

Michael Kay
http://www.saxonica.com/ 

> -----Original Message-----
> From: Bradley, Peter [mailto:pbradley@xxxxxxxxxx] 
> Sent: 30 September 2008 14:07
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] Implementing a (fairly) complex business rule
> 
> I have a business rule that says that if the value of the 
> REDUCEDI element is "00" and if the value of the DOMICILE 
> element is in a list of values comprising XG, XH, XI, XK, XL, 
> GG, JE and IM then a POSTCODE element must be present.  It 
> should not be present otherwise.
> 
> If the POSTCODE element is present and has a NULL value, then 
> a ReasonForNull attribute should be included, with a value of "1".
> 
> If the POSTCODE element is present and has a value, that 
> value should be output and the ReasonForNull attribute should 
> not be present.
> 
> I have expressed this as follows:
> 
> <!-- NULL is valid for a postcode -->
> <xsl:if
> test="/s0:HesaSqlExplicit_Response/s0:Institution/s0:Student/s
> 0:Instance
> /s0:REDUCEDI = '00'">
>   <xsl:if
>   test="s0:DOMICILE='XF' or s0:DOMICILE='XG' or s0:DOMICILE='XH' or
>   s0:DOMICILE='XI' or s0:DOMICILE='XK' or s0:DOMICILE='XL' or
>   s0:DOMICILE='GG' or s0:DOMICILE='JE' or s0:DOMICILE='IM'">
>     <POSTCODE>
>       <xsl:if test="string-length(s0:POSTCODE/text() = 0)">
>         <xsl:attribute name="ReasonForNull">
>           <xsl:text>1</xsl:text>
>         </xsl:attribute>
>       </xsl:if>
>       <xsl:if test="string-length(s0:POSTCODE/text()) > 0">
>         <xsl:value-of select="s0:POSTCODE/text()"/>
>       </xsl:if>
>     </POSTCODE>
>   </xsl:if>
> </xsl:if>
> 
> However, in my output I am getting POSTCODE elements that 
> both have a value and also have a ReasonForNull attribute 
> with a value of "1".
> 
> Can anyone put me out of my misery?  I just cannot see how 
> this can happen.
> 
> Thanks
> 
> 
> Peter

Current Thread