xsl-list
[Top] [All Lists]

Re: [xsl] Question about grouping attributes using keys

2007-04-19 09:33:32
I can suggest something like below (tested with IE 6.0):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                      xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                      version="1.0">

  <xsl:output method="html" />

  <xsl:key name="UNIQUE_ATTRS" match="ITEM" use="@ATTR" />
  <xsl:key name="UNIQUE_ELEMS" match="ITEM" use="ELEM" />

  <xsl:template match="/">
    <xsl:call-template name="test">
      <xsl:with-param name="theKey" select="'UNIQUE_ELEMS'"/>
      <xsl:with-param name="theName" select="'ELEM'"/>
    </xsl:call-template>
    <xsl:call-template name="test">
      <xsl:with-param name="theKey" select="'UNIQUE_ATTRS'"/>
      <xsl:with-param name="theName" select="'ATTR'"/>
    </xsl:call-template>
  </xsl:template>

  <xsl:template name="test">
    <xsl:param name="theKey" select="." />
    <xsl:param name="theName" select="." />
    <p>
      <xsl:value-of select="concat('key: ', $theKey)" /><br/>
      <xsl:value-of select="concat('node: ', $theName)"/><br/>
      <xsl:text>values:</xsl:text>
      <xsl:variable name="rtf">
        <xsl:for-each select="ROOT/ITEM[generate-id() =
generate-id(key($theKey, ELEM)[1])]">
          <xsl:value-of select="." />
        </xsl:for-each>
        <xsl:for-each select="ROOT/ITEM[generate-id() =
generate-id(key($theKey, @ATTR)[1])]">
           <xsl:value-of select="@ATTR" /><xsl:text> </xsl:text>
        </xsl:for-each>
      </xsl:variable>
      <xsl:value-of select="msxsl:node-set($rtf)" />
    </p>
  </xsl:template>

</xsl:stylesheet>

It seems, it's difficult to make the stylesheet more generic than this.

On 4/19/07, Waters, Tyler S FOR:EX 
<Tyler(_dot_)Waters(_at_)gov(_dot_)bc(_dot_)ca> wrote:
I'm trying to write a generic function to output a list of unique values
on a selected node, whether it be an Element or Attribute.  I've got the
Element portion working fine, but Attributes don't seem to want to run
through the for-each loop....  Here's a test which highlights this:

test.xml:

       <?xml version="1.0" encoding="ISO8859-1" ?>
       <?xml-stylesheet type="text/xsl" href="test.xsl"?>
       <ROOT>
               <ITEM ATTR="A1">
                       <ELEM>E1</ELEM>
               </ITEM>
               <ITEM ATTR="A1">
                       <ELEM>E1</ELEM>
               </ITEM>
               <ITEM ATTR="A2">
                       <ELEM>E2</ELEM>
               </ITEM>
               <ITEM ATTR="A2">
                       <ELEM>E2</ELEM>
               </ITEM>
               <ITEM ATTR="A3">
                       <ELEM>E3</ELEM>
               </ITEM>
               <ITEM ATTR="A3">
                       <ELEM>E3</ELEM>
               </ITEM>
       </ROOT>

test.xsl:

       <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="1.0">
       <xsl:output method="html" />
       <xsl:key name="UNIQUE_ATTRS" match="ITEM" use="@ATTR" />
       <xsl:key name="UNIQUE_ELEMS" match="ITEM" use="ELEM" />

       <xsl:template match="/">
               <xsl:call-template name="test">
                       <xsl:with-param name="theKey"
select="'UNIQUE_ELEMS'"/>
                       <xsl:with-param name="theName" select="'ELEM'"/>
               </xsl:call-template>
               <xsl:call-template name="test">
                       <xsl:with-param name="theKey"
select="'UNIQUE_ATTRS'"/>
                       <xsl:with-param name="theName" select="'ATTR'"/>
               </xsl:call-template>
       </xsl:template>

       <xsl:template name="test">
               <xsl:param name="theKey" select="." />
               <xsl:param name="theName" select="." />
               <p>
               <xsl:value-of select="concat('key: ', $theKey)" /><br/>
               <xsl:value-of select="concat('node: ', $theName)"
/><br/>
               <xsl:text>values:</xsl:text>
               <xsl:for-each select="ROOT/ITEM[ generate-id() =
generate-id( key( $theKey, *[local-name()=$theName] ) [1] ) ]">
                       <xsl:value-of select="." />
               </xsl:for-each>
               </p>
       </xsl:template>
       </xsl:stylesheet>

Opening "test.xml" returns:

       key: UNIQUE_ELEMS
       node: ELEM
       values: E1 E2 E3

       key: UNIQUE_ATTRS
       node: ATTR
       values:

Why is it that "A1 A2 A3" is not returned for the ATTR node?  Is there
any way to write a generic for-each select expression that takes the
node name & key name and works for both elements and attributes?   Any
help is greatly appreciated

Thanks,
-Tyler Waters

--
Regards,
Mukul Gandhi

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