xsl-list
[Top] [All Lists]

RE: sorting and 0 div boolean

2006-02-14 11:47:44
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(_at_)cclaflorida(_dot_)org] 
Sent: 14 February 2006 18:24
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: [xsl] 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(_at_)cclaflorida(_dot_)org

<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>



--~------------------------------------------------------------------
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>
--~--



<Prev in Thread] Current Thread [Next in Thread>