Re: [xsl] Xalan bug?

Subject: Re: [xsl] Xalan bug?
From: Mukul Gandhi <mukul_gandhi@xxxxxxxxx>
Date: Thu, 2 Dec 2004 18:35:41 -0800 (PST)
Hi Geert,
  Thanks for your observations..

Please note: I am getting correct result for
group-size of 1,2,3 & 4. But with 5 and above, result
is wrong(Only with Xalan; among Xalan-J2.6.0, Saxon 8,
and MSXSL 4 with whom I tested).

One another interesting observation is that, in this
part of the code

<!-- display group members -->
<xsl:for-each select=". |
preceding-sibling::node[position() &lt;= ($group-size
- 1)]">         
   <xsl:value-of select="." />
   <xsl:if test="(position() mod $group-size) !=
0">
     <xsl:text>,</xsl:text>
   </xsl:if>       
</xsl:for-each>

I wanted to generate , (commas) - to seperate group
members, actually with this code
<xsl:if test="position() != last()">
  <xsl:text>,</xsl:text>
</xsl:if>
But this is not working.. 

So I wrote, 
<xsl:if test="(position() mod $group-size) != 0">

Is'nt this surprising?

Regards,
Mukul

--- Geert Josten <Geert.Josten@xxxxxxxxxxx> wrote:

> Hi Mukul,
> 
> The trouble rests in the expression that takes the
> preceding nodes that sound belong in the last 
> group together with the last node:
> 
>         <xsl:for-each select=". |
> preceding-sibling::node[position() &lt; $n]">
> 
> I'm very uncertain on what the XPath rec sais on how
> position() should be interpreted. I tried to 
> wrap preceding-sibling::node in braces, but that
> results in them being put back into doc order (as 
> it should!), so you get a in the last group instead
> of one of the last... :-P
> 
> Considering that preceding-sibling::node is failing,
> one should expect that only the left part of 
> the union (.) returns a value. But, the result is
> _not_ showing the last node, but the first of that 
> last group (which is correct). Moreover, a ',' is
> shown, so the context list is filled with more 
> than one node! The for-each is definitely failing!!!
> 
> A less mind boggling expression, that works with all
> parsers as well (I guess) is:
> 
>         <xsl:for-each select="../node[position() >
> $m]">
> 
> with m defined as:
> 
>     <xsl:variable name="m" select="floor(count(node)
> div $group-size) * $group-size" />
> 
> 
> Though I really think, you have conceived a complex
> solution for a not necessarily that complex a 
> problem...
> 
> 
> Cheers,
> Geert
> 
> 
> Mukul Gandhi wrote:
> 
> > I have added some comments in my logic(shown
> below) to
> > help in understanding..
> > 
> > <?xml version="1.0"?> 
> > <xsl:stylesheet
> > xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
> > version="1.0">
> >  
> > <xsl:output method="text" /> 
> > 
> > <xsl:param name="group-size" select="3" />
> >  
> > <xsl:template match="/Parent">
> >    <!-- calculate the no of "node" elements, which
> are
> > left as a fraction; which are to be displayed in
> the
> > last group -->
> >    <xsl:variable name="n" select="count(node) -
> > (floor((count(node) div $group-size)) *
> $group-size)"
> > />
> >    
> >    <xsl:for-each select="node">
> >      <!-- determine group boundary; this if test
> stops
> > at the last "node" element of the group -->
> >      <xsl:if test="(position() mod $group-size) =
> 0">
> >        group <xsl:value-of
> select="floor(position()
> > div $group-size)" /><xsl:text> - </xsl:text>
> >        <!-- display group members -->
> >        <xsl:for-each select=". |
> > preceding-sibling::node[position() &lt;=
> ($group-size
> > - 1)]">         
> >          <xsl:value-of select="." /><xsl:if
> > test="(position() mod $group-size) !=
> > 0"><xsl:text>,</xsl:text></xsl:if>       
> >        </xsl:for-each>
> >        <xsl:text>
</xsl:text>
> >      </xsl:if> 
> >      <!-- this if test processes the last group;
> whose
> > number of group members will be less than the
> > group-size -->
> >      <xsl:if test="((position() = last()) and
> > ((position() mod $group-size) != 0))">
> >        group <xsl:value-of
> select="floor(position()
> > div $group-size) + 1" /><xsl:text> - </xsl:text>
> >        <xsl:for-each select=". |
> > preceding-sibling::node[position() &lt; $n]">
> >          <xsl:value-of select="." /><xsl:if
> > test="position() !=
> > last()"><xsl:text>,</xsl:text></xsl:if> 
> >        </xsl:for-each>
> >        <xsl:text>
</xsl:text>
> >      </xsl:if>
> >    </xsl:for-each>
> > </xsl:template>
> >    
> > </xsl:stylesheet>
> > 
> > I would be happy to see any discussion on this
> post..
> > 
> > Regards,
> > Mukul
> > 
> > PS: I have posted it as a bug on Xalan site. 
> > 
> > --- Mukul Gandhi <mukul_gandhi@xxxxxxxxx> wrote:
> > 
> > 
> >>Hello,
> >>I was solving a problem posted by a user at
> >>microsoft.public.xsl newsgroup. I seem to have
> been
> >>hit by a Xalan bug(Xalan-J 2.6.0), which I wish to
> >>confirm with members here.. 
> >>
> >>The problem posted was -
> >>Subject: Grouping by two or any number
> >>--------------------------------------
> >>i have the following xml
> >>
> >><Parent>
> >>  <node>a</node>
> >>  <node>s</node>
> >>  <node>d</node>
> >>  <node>f</node>
> >>  <node>g</node>
> >>  <node>h</node>
> >>  <node>j</node>
> >>  <node>k</node>
> >>  <node>l</node>
> >></Parent>
> >>
> >>
> >>Need to print in following format (into groups of
> >>two)
> >>
> >>group 1 - a,s
> >>group 2 - d,f
> >>group 3 - g,h
> >>group 4 - j,k
> >>group 5 - l
> >>
> >>I wrote the following stylesheet -
> >>
> >><?xml version="1.0"?> 
> >><xsl:stylesheet
> >>xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
> >>version="1.0">
> >> 
> >><xsl:output method="text" /> 
> >>
> >><xsl:param name="group-size" select="3" />
> >> 
> >><xsl:template match="/Parent">
> >>   <xsl:variable name="n" select="count(node) -
> >>(floor((count(node) div $group-size)) *
> >>$group-size)"
> >>/>
> >>   
> >>   <xsl:for-each select="node">
> >>     <xsl:if test="(position() mod $group-size) =
> >>0">
> >>       group <xsl:value-of
> select="floor(position()
> >>div $group-size)" /><xsl:text> - </xsl:text>
> >>       <xsl:for-each select=". |
> >>preceding-sibling::node[position() &lt;=
> >>($group-size
> >>- 1)]">         
> >>         <xsl:value-of select="." /><xsl:if
> >>test="(position() mod $group-size) !=
> >>0"><xsl:text>,</xsl:text></xsl:if>       
> >>       </xsl:for-each>
> >>       <xsl:text>
> > 
> > </xsl:text>
> > 
> >>     </xsl:if> 
> >>     <xsl:if test="((position() = last()) and
> >>((position() mod $group-size) != 0))">
> >>       group <xsl:value-of
> select="floor(position()
> >>div $group-size) + 1" /><xsl:text> - </xsl:text>
> >>       <xsl:for-each select=". |
> >>preceding-sibling::node[position() &lt; $n]">
> >>         <xsl:value-of select="." /><xsl:if
> >>test="position() !=
> >>last()"><xsl:text>,</xsl:text></xsl:if> 
> >>       </xsl:for-each>
> >>       <xsl:text>
> > 
> > </xsl:text>
> > 
> >>     </xsl:if>
> >>   </xsl:for-each>
> >></xsl:template>
> >>   
> >></xsl:stylesheet>
> >>
> >>I invoke Xalan like this:
> >>java org.apache.xalan.xslt.Process -in file.xml
> -xsl
> >>file.xsl -PARAM group-size 2
> >>
> >>The output is fine for -PARAM group-size values of
> >>1,2,3 & 4. But for -PARAM group-size values of 5
> and
> >>above, the ouput is not coming as expected. For
> >>e.g.,
> >>for -PARAM group-size 5, the output received is -
> >>
> >>group 1 - a,s,d,f,g
> >>group 2 - h,
> >>
> >>I tested the same XSL with Saxon-SA 8.1.1 and
> MSXSL
> >>4,
> >>and both produce correct result for all the cases.
> >>Both Saxon and MSXSL produce the following output
> >>for
> >>group-size=5 -
> >>
> >>group 1 - a,s,d,f,g
> >>group 2 - h,j,k,l
> >>
> >>Does this look like a Xalan bug?
> >>
> >>Regards,
> >>Mukul
> > 
> > 
> > 
> > 
> > 	
> > 		
> > __________________________________ 
> > Do you Yahoo!? 
> > Yahoo! Mail - You care about security. So do we. 
> > http://promotions.yahoo.com/new_mail
> > 
> > 
> > 
> 
> -- 
> Geert.Josten@xxxxxxxxxxx
> IT-consultant at Daidalos BV, Zoetermeer (NL)
> 
> http://www.daidalos.nl/
> tel:+31-(0)79-3316961
> fax:+31-(0)79-3316464
> 
> GPG: 1024D/12DEBB50



		
__________________________________ 
Do you Yahoo!? 
Yahoo! Mail - 250MB free storage. Do more. Manage less. 
http://info.mail.yahoo.com/mail_250

Current Thread