xsl-list
[Top] [All Lists]

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

2008-09-30 11:13:05
Wendell,

That's very clear.  Thanks.  And your diagnosis is spot on, of course.

I remember you helping me out some years ago when I was "doing" xslt as
part of an MSc course.  This is my first look at xslt since then, so you
can imagine I've forgotten quite a lot.  It's coming back though -
although you may have to put up with me plaguing the list for a while!

(I got the MSc, BTW, with distinction)

:)


Peter


-----Original Message-----
From: Wendell Piez [mailto:wapiez(_at_)mulberrytech(_dot_)com] 
Sent: 30 September 2008 15:39
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: Re: [xsl] Implementing a (fairly) complex business rule

Peter,

At 09:07 AM 9/30/2008, you wrote:
      <xsl:if test="string-length(s0:POSTCODE/text() = 0)">
        <xsl:attribute name="ReasonForNull">
          <xsl:text>1</xsl:text>
        </xsl:attribute>
      </xsl:if>

This won't work as a test for whether s0:POSTCODE has a null value. 
For one thing, "null value" is undefined in XSLT. Null values in your 
XML in any number of ways.

More seriously, however, you have

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

This measures the length of the string returned by casting the 
expression "sO:POSTCODE/text()=0". This is a numeric comparison, 
returning true if you have <s0:POSTCODE>0</s0:POSTCODE> (or some 
other lexical representation of 0, such as "0.0"), and false 
otherwise. Cast to a string, this is either "true" or "false". (In 
XPath 1.0. In XPath 2.0 you would get an error for trying to measure 
the string length of a Boolean.) The string length of "false" is 5, 
"true" is 4. Either 4 or 5 always tests true. So you will always get 
your @ReasonForNull[.='1'].

So you are looking at one of those unhelpful occasions where XPath 
silently errors on you, without telling you so, by faithfully 
executing what you have asked for.

Now, I'm guessing you meant

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

This looks like it should work: it measures the length of 
s0:POSTCODE's text node, and returns true if it is 0.

However, I wouldn't recommend this either. It will test true when 
s0:POSTCODE has no value at all, since in that case, it has no text 
node, and the string length of a node that does not exist is zero.

But it's fairly brittle, since it will fail if your input, for example,
has

<s0:POSTCODE>  </s0:POSTCODE>

(i.e. whitespace-only content but not zero-length)

which comes back to my opening remark that the notion of "null value" 
has to be defined before we can write the expression properly.

This is not an infrequent problem. Often a defensive coder will 
define "null value" as "no value or whitespace-only value". In this 
case, a good test is:

<xsl:if test="not(normalize-space(s0:POSTCODE))">
... </xsl:if>

The normalize-space() function collapses a whitespace-only value into 
an empty string. The string value is cast to a Boolean for the not() 
function, by the rule that empty strings are false and non-empty 
strings are true. not(), of course, inverts this Boolean value, so we 
get true when s0:POSTCODE has no value (except possibly for whitespace).

Saying s0:POSTCODE/text() isn't necessary, since the string value of 
the element itself will do. Indeed, if any comments or processing 
instructions are present, looking at the first text node (in XSLT 
1.0) won't do: we want the value of s0:POSTCODE itself.

So the problems here reduce to (a) having the parethesis misplaced, 
and then potentially (b) writing a test which doesn't necessarily 
perform the test you actually want. We see expressions like (b) since 
they are common in other languages. But in XSLT (or actually, here, 
XPath), other idioms frequently turn out to be both cleaner and more 
robust (while demanding a bit of an education to learn).

Then too, sometimes the definition of "null value" includes values 
like "0" or "NULL". Which is a different story altogether.

Cheers,
Wendell



======================================================================
Wendell Piez                            
mailto:wapiez(_at_)mulberrytech(_dot_)com
Mulberry Technologies, Inc.                http://www.mulberrytech.com
17 West Jefferson Street                    Direct Phone: 301/315-9635
Suite 207                                          Phone: 301/315-9631
Rockville, MD  20850                                 Fax: 301/315-8285
----------------------------------------------------------------------
   Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--