xsl-list
[Top] [All Lists]

RE: key grouping with non-existing or empty elements

2003-01-05 11:57:34
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(_dot_)H(_dot_)Kay(_at_)ntlworld(_dot_)com
work: Michael(_dot_)Kay(_at_)softwareag(_dot_)com 

-----Original Message-----
From: owner-xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com 
[mailto:owner-xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com] On Behalf Of 
Xiaocun Xu
Sent: 03 January 2003 19:48
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
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(_dot_)heinicke(_at_)gmx(_dot_)de> 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[(_at_)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[(_at_)column='6'])"/>

<xsl:template match="rootelement">
    <table border="1">
      <xsl:apply-templates select="row[generate-id()
=
generate-id(key('rows',
string(cell[(_at_)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[(_at_)column='6']"/>"<xsl:text/>
      </td>
    </tr>
    <xsl:apply-templates select="key('rows',
string(cell[(_at_)column='6']))"/>
</xsl:template>

<xsl:template match="row">
    <tr>
      <td>
        <xsl:value-of select="cell[(_at_)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[(_at_)row
&gt; $LineItemHeaderRow and (cell[(_at_)column=$LineItemLotColumn])]"
use="cell[(_at_)column=$LineItemLotColumn]"/>
2. create a separate variable that contains rows
that
does not have cell 6 element:
  <xsl:variable name="LineItemDefaultLot"
select="//row[(_at_)row &gt; $LineItemHeaderRow and 
not(cell[(_at_)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(_at_)yahoo(_dot_)com




 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



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