After Josh's good analysis and solution for your problem I want to add some comments from the XSLT point of view. The solution is "sub-optimal", you have to bad axes in your expression: the descendant axis ('//') and the preceding axis. Both used in combination can slow down the processing extremely if you have a bigger data base to transform.

The first can be solved by using the more exact XPath:
<xsl:variable name="unique-rows" select="/page/include/tables/table/row/[EMAIL PROTECTED]'ID'][not(.=preceding::[EMAIL PROTECTED]'ID'])]"/>


The second one at least partly by switching to preceding-sibling:
<xsl:variable name="unique-rows" select="/page/include/tables/table/row[not([EMAIL PROTECTED]'ID'] = preceding-sibling::[EMAIL PROTECTED]'ID'])]/[EMAIL PROTECTED]'ID']"/>


But there are still a few problems: don't use global variables if not necessary. In your sample you can simply move the $unique-rows variable into the first template without changing anything else. (But maybe you only have shortened the stylesheet ...)

Then you are obfuscating the processing flow a bit in the stylesheet. If you or someone else later wants to maintain the stylesheet the uniqueness of the row processed at a template matching field makes it not easier. Also selecting key()[1] and key()[2] are a bit obfuscating. Show the real sense of them! You can change it like the following:

<xsl:variable name="unique-rows" select="/page/include/tables/table/row[not([EMAIL PROTECTED]'ID'] = preceding-sibling::[EMAIL PROTECTED]'ID'])]"/>

and later on the template:

<xsl:template match="row">
<xsl:variable name="val" select="[EMAIL PROTECTED]'ID']"/>
<row id="{position()}">
<field name="KEY"><xsl:value-of select="key('rows', $val)[EMAIL PROTECTED]'PARAM']='KEY']/[EMAIL PROTECTED]'VALUE']"/></field>
<field name="VALUE"><xsl:value-of select="key('rows', $val)[EMAIL PROTECTED]'PARAM']='VALUE']/[EMAIL PROTECTED]'VALUE']"/></field>
</row>
</xsl:template>


But as you can see the XPath for $unique-rows is still really long and more or less unreadable. A clever man named Steve Muench invented a grouping method, in the meantime called Muenchian Method (http://www.jenitennison.com/xslt/grouping/muenchian.html). One part of it you already have set up: the key declaration. The missing part is the selection of the unique rows:

<xsl:variable name="unique-rows" select="/page/include/tables/table/row
[count(. | key('rows', [EMAIL PROTECTED]'ID'])[1]) = 1]"/>

There are at least 2 advantages: It's "standardized" in the sense of well-known. And the processing is optimized (XSLT processors can further optimize it as it is a standardized technique).

If you then add a further modularization ("templatization") for accessing KEY and VALUE you get the stylesheet I attached.

I hope it helps :-)

Joerg
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

  <xsl:param name="name"/>
  <xsl:key name="rows" match="row" use="[EMAIL PROTECTED]'ID']"/>
  <xsl:key name="param-fields" match="[EMAIL PROTECTED]'VALUE']" use="concat(../[EMAIL PROTECTED]'ID'], '::', ../[EMAIL PROTECTED]'PARAM'])"/>

  <xsl:template match="/">
    <xsl:variable name="unique-rows" select="/page/include/tables/table/row
                                             [count(. | key('rows', [EMAIL PROTECTED]'ID'])[1]) = 1]"/>
    <table name="{$name}">
      <xsl:apply-templates select="$unique-rows"/>
    </table>
  </xsl:template>

  <xsl:template match="row">
    <xsl:variable name="id" select="[EMAIL PROTECTED]'ID']"/>
    <row id="{position()}">
      <xsl:apply-templates select="key('param-fields', concat($id, '::KEY'))"/>
      <xsl:apply-templates select="key('param-fields', concat($id, '::VALUE'))"/>
    </row>
  </xsl:template>

  <xsl:template match="field">
    <field name="{../[EMAIL PROTECTED]'PARAM']}">
      <xsl:value-of select="."/>
    </field>
  </xsl:template>
</xsl:stylesheet>


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to