RE: [xsl] key grouping with non-existing or empty elements

Subject: RE: [xsl] key grouping with non-existing or empty elements
From: "Michael Kay" <michael.h.kay@xxxxxxxxxxxx>
Date: Sun, 5 Jan 2003 18:57:34 -0000
The "use" attribute identifies a set of values that can each be used to
find the "match" item. For example, match="book" use="author" will index
the book by each of its authors. If the book has no authors, then it
will not be indexed and no key() expression using this key will find it.

If books have zero-or-one authors, then you can write match="book"
use="string(author)", and a book with no authors will then be
retrievable using the key value "".

Michael Kay
Software AG
home: Michael.H.Kay@xxxxxxxxxxxx
work: Michael.Kay@xxxxxxxxxxxxxx 

> -----Original Message-----
> From: owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx 
> [mailto:owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx] On Behalf Of Xiaocun Xu
> Sent: 03 January 2003 19:48
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: Re: [xsl] key grouping with non-existing or empty elements
> 
> 
> Hi, Joerg:
> 
>   I tried:
> <xsl:apply-templates select="key('lineitemLotsKey', 
> string(''))" mode="LineItem"/> and <xsl:apply-templates 
> select="key('lineitemLotsKey', '')" mode="LineItem"/> both 
> did not find the rows with non-existing or empty key 
> elements.  Any particular caution I need to pay here?
> 
> Thanks,
> Xiaocun
> 
> --- Joerg Heinicke <joerg.heinicke@xxxxxx> wrote:
> > Hello Xiaocun,
> > 
> > getting what you want is really simple using keys,
> > you only must set it
> > up as top-level element and use
> > string(cell[@column='6']) as grouping
> > key. So both non-existing element and empty element
> > are evaluated to 
> > empty string "":
> > 
> > <xsl:key name="rows" match="row" use="string(cell[@column='6'])"/>
> > 
> > <xsl:template match="rootelement">
> >     <table border="1">
> >       <xsl:apply-templates select="row[generate-id()
> > =
> > generate-id(key('rows',
> > string(cell[@column='6'])))]" mode="start-group"/>
> >     </table>
> > </xsl:template>
> > 
> > <xsl:template match="row" mode="start-group">
> >     <tr>
> >       <td>starting a new group with content of
> > column 6: "<xsl:text/>
> >         <xsl:value-of select="cell[@column='6']"/>"<xsl:text/>
> >       </td>
> >     </tr>
> >     <xsl:apply-templates select="key('rows',
> > string(cell[@column='6']))"/>
> > </xsl:template>
> > 
> > <xsl:template match="row">
> >     <tr>
> >       <td>
> >         <xsl:value-of select="cell[@column='1']"/>
> >       </td>
> >     </tr>
> > </xsl:template>
> > 
> > Regards,
> > 
> > Joerg
> > 
> > Xiaocun Xu wrote:
> > > Hi,
> > > 
> > > 	I have a question regarding grouping with key.
> > > Following is the input XML example:
> > > 
> > > <row row="1">
> > > 	<cell column="1">default_item1</cell>
> > > 	<cell column="6"></cell>
> > > </row>
> > > <row row="2">
> > > 	<cell column="1">default_item2</cell>
> > > </row>
> > > <row row="3">
> > > 	<cell column="1">lot01_item1</cell>
> > > 	<cell column="6">lot01</cell>
> > > </row>
> > > <row row="4">
> > > 	<cell column="1">lot02_item2</cell>
> > > 	<cell column="6">lot02</cell>
> > > </row>
> > > 
> > > I have a number of items that need to be grouped
> > by
> > > lot (cell[column=6]).  As you can see, this cell
> > is
> > > optional.
> > > I need to group rows that does not have cell[6]
> > and
> > > rows have cell[6] as empty string into the same
> > group,
> > > then process each of the row within the group via: 
> > > <xsl:apply-templates
> > select="key('lineitemLotsKey',
> > > $lotName)" mode="LineItem"/>
> > > 
> > > 	The way I currently handling this is not very
> > > elegent:
> > > 1. create a key on lot (cell 6) for all rows with
> > cell
> > > 6 element:
> > > 	<xsl:variable name="LineItemLotColumn"
> > select="6"/>
> > > 	<xsl:key name="lineitemLotsKey" match="//row[@row
> > > &gt; $LineItemHeaderRow and (cell[@column=$LineItemLotColumn])]"
> > > use="cell[@column=$LineItemLotColumn]"/>
> > > 2. create a separate variable that contains rows
> > that
> > > does not have cell 6 element:
> > > 	<xsl:variable name="LineItemDefaultLot"
> > > select="//row[@row &gt; $LineItemHeaderRow and 
> > > not(cell[@column=$LineItemLotColumn])]"/>
> > > 3. process $LineItemDefaultLot separately.
> > > 4. when process rows in key lineitemLotsKey, check
> > for
> > > string(cell[6]).  If empty, then does similar
> > > processing as #3.
> > > 
> > > Of course, a slight improvement would be for #2,
> > > instead of get all rows that does not have cell 6
> > > element, also get all rows that has cell 6 element
> > > equal to empty string.  That way, I would not need
> > to
> > > check for string(cell[6]) in step #4.
> > > 
> > > Is there a more elegent way than these above?
> > > 
> > > Thanks,
> > > 
> > > Xiaocun
> > > xiaocunxu@xxxxxxxxx
> > 
> > 
> > 
> > 
> >  XSL-List info and archive:
> > http://www.mulberrytech.com/xsl/xsl-list
> > 
> 
> 
> __________________________________________________
> Do you Yahoo!?
> Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
> http://mailplus.yahoo.com
> 
>  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
> 


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread