[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

RE: sorting and 0 div boolean

Subject: RE: sorting and 0 div boolean
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Tue, 14 Feb 2006 18:47:44 -0000
sort div
This "0 div boolean" is a cunning David Carlisle special device to simulate
a conditional expression. It stops working in 2.0 because numeric literals
such as "0" or "1" are now interpreted as integers rather than doubles, and
integer division by zero is a hard error, whereas double division by zero
returns infinity, which you can use in a cunning way as an argument to
substring().

The way forward depends on whether you want to move to a pure 2.0 solution,
or to have a solution that works under both releases. For a solution that
works under both versions, the simplest approach is to change the literal 0
to number("0") which gives you a double zero under both versions. 

For a 2.0 solution, we need to reverse engineer the expression

>      <xsl:sort select="concat(
          substring(substring-after(.,' '), 
                    0 div boolean($stop-words
               [starts-with(translate(current(), $uppercase, $lowercase), 
                  concat(translate(., $uppercase, $lowercase), ' '))])), 
                     substring(., 0 div not 
                         ($stop-words[starts-with(translate(current(),
$uppercase, $lowercase), 
              concat(translate(., $uppercase, $lowercase), ' '))])))"/> 

which is a bit of a monster.

Basically, substring(X, 0 div boolean(B)) means

if (B) then X else ""

So I think the above expression reduces to

      <xsl:sort select="concat(
          if ($stop-words[starts-with(lower-case(current()),
concat(lower-case(.), ' '))]) 
            then substring-after(.,' ') 
            else '', 
          if ($stop-words[starts-with(lower-case(current()),
concat(lower-case(.), ' '))]) 
            then '' 
            else .)"/> 

which in turn reduces to

      <xsl:sort select="
          if ($stop-words[starts-with(lower-case(current()),
concat(lower-case(.), ' '))]) 
            then substring-after(.,' ') 
            else ."/>

I'd encourage you not to use Saxon 7.7, however. The specs were pretty
unstable at the time 7.7 came out, and it's now about 10 releases out of
date. Go straight to 8.6.1.

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

> -----Original Message-----
> From: Susan Campbell [mailto:SCampbell@xxxxxxxxxxxxxxx] 
> Sent: 14 February 2006 18:24
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject:  sorting and 0 div boolean
> 
> This code worked but now it doesn't work.   We had a software upgrade
> and our processor is contained within the other software.  
> When the sort
> worked we were using Saxon 6.4.2.  We're now using Saxon 7.7. 
>  This code
> still works in the old version, but not in the new.  This code now
> returns a parse error, "Division by zero."  I read the FAQ about
> 'Division by zero' but format-number doesn't help me here. 
> 
> Is there another way to sort this and ignore the stop words I 
> have here?
> The problem section of my xsl is here, followed by a snippet 
> of the xml
> I'm trying to transform.
> Thanks,
> Susan Campbell
> scampbell@xxxxxxxxxxxxxxx
> 
> <xsl:stylesheet
>    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
>    xmlns:sw="http://my.stopwords/sw"
>    exclude-result-prefixes="sw">
> 
> <sw:stop>
>    <word>the</word>
>    <word>a</word>
>    <word>an</word>
> </sw:stop>
> 
> <xsl:variable name="stop-words"
> select="document('')/xsl:stylesheet/sw:stop/word"/>
> <xsl:variable name="lowercase" select="'abcdefghijklmnopqrstuvwxyz'"/>
> <xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUV'"/>
> 
> <xsl:template match="/">
> <xsl:call-template name="header"/>
>      <xsl:for-each select="//section-02/title">
>      <xsl:sort select="concat(substring(substring-after(.,' '), 0 div
> boolean
>              ($stop-words[starts-with(translate(current(), $uppercase,
> $lowercase), 
>              concat(translate(., $uppercase, $lowercase), ' '))])),
> substring(., 0 div not
>              ($stop-words[starts-with(translate(current(), $uppercase,
> $lowercase), 
>              concat(translate(., $uppercase, $lowercase), ' 
> '))])))"/> 
>           <xsl:if test="position() = 1">
>           <xsl:call-template name="section-02">
>              <xsl:with-param name="header" select="'header'"/>
>           </xsl:call-template>
>        </xsl:if>
>        <xsl:call-template name="section-02"/>
>     </xsl:for-each>
> </xsl:template>
> </xsl:stylesheet>
> 
> 
> The XML section I'm trying to sort looks like this;.
> <section-02>
> <title>The African American review.</title>
> <arrivals>2</arrivals>
> </section-02>
> 
> <section-02>
> <title>Agricultural research /</title>
> <arrivals>8</arrivals>
> </section-02>
> 
> <section-02>
> <title>The American biology teacher.</title>
> <arrivals>5</arrivals>
> </section-02>
> 
> <section-02>
> <title>The American journal of nursing.</title>
> <arrivals>6</arrivals>
> </section-02>
> 
> <section-02>
> <title>Air &amp; space Smithsonian.</title>
> <arrivals>2</arrivals>
> </section-02>
> 
> <section-02>
> <title>An American Story.</title>
> <arrivals>20</arrivals>
> </section-02>

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.