xsl-list
[Top] [All Lists]

Re: problem with keys and Meunchian method

2004-11-17 14:37:47
At 2004-11-17 12:10 -0800, mark_fletcher(_at_)peoplesoft(_dot_)com wrote:
I'm having a problem pulling distinct nodes out of some xml with duplicate
values at multiple levels.

I find that variable-based grouping is far more effective for multiple-level distinction because key-based grouping is always working in document-wide scope.

In all cases, I want to get the data from the
last node of a set that shares duplicate values.  (This xml will be in a
file that gets appended to multiple times.  So I can assume that the last
tags are the most current.)

Fine.

In the xml below, what I'm trying to do is get a list of distinct book/code
values from the last prodline where name=PL1.

I'm assuming, though, that you'd want to do this for each of your product lines.

But I'm having no luck getting a list of distinct book/code values from
this particular prodline.  I've tried creating keys and using the Meunchian
method of comparing generate-id() values, but to no avail. Any help would
be greatly appreciated!

I suggest not using the Meunchian method because of its document scope and to use the variable-based method because you can then work within a selected scope. If you Google for variable-based grouping you'll find a number of examples I've posted of doing grouping within a limited scope.

A working solution to your problem is below.

I hope this helps.

.................. Ken


t:\ftemp>type mark.xml
<prodlines>
  <prodline>
    <name>Product Line 1</name>
    <code>PL1</code>
    <product>
      <name>Product 1</name>
      <code>P1</code>
      <book>
        <name>Book 1</name>
        <code>B1</code>
      </book>
      <book>
        <name>Book 2</name>
        <code>B2</code>
      </book>
    </product>
    <product>
      <name>Product 2</name>
      <code>P2</code>
      <book>
        <name>Book 1</name>
        <code>B1</code>
      </book>
      <book>
        <name>Book 3</name>
        <code>B3</code>
      </book>
      <book>
        <name>Book 4</name>
        <code>B4</code>
      </book>
    </product>
  </prodline>
  <prodline>
    <name>Product Line 2</name>
    <code>PL2</code>
    <product>
      <name>Product 1</name>
      <code>P1</code>
      <book>
        <name>Book 1</name>
        <code>B1</code>
      </book>
    </product>
  </prodline>
  <prodline>
    <name>Product Line 1 (ver 2)</name>
    <code>PL1</code>
    <product>
      <name>Product 1</name>
      <code>P1</code>
      <book>
        <name>Book 1</name>
        <code>B1</code>
      </book>
      <book>
        <name>Book 2</name>
        <code>B2</code>
      </book>
      <book>
        <name>Book 5</name>
        <code>B5</code>
      </book>
    </product>
    <product>
      <name>Product 2</name>
      <code>P2</code>
      <book>
        <name>Book 1</name>
        <code>B1</code>
      </book>
      <book>
        <name>Book 2</name>
        <code>B2</code>
      </book>
      <book>
        <name>Book 3</name>
        <code>B3</code>
      </book>
      <book>
        <name>Book 4</name>
        <code>B4</code>
      </book>
    </product>
  </prodline>
</prodlines>

t:\ftemp>type mark.xsl
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                version="1.0">

<xsl:output method="text"/>

<xsl:template match="/">
  <xsl:for-each select="/prodlines/prodline">
    <xsl:variable name="bookcodes" select="product/book"/>
Product line: <xsl:value-of select="name"/>
    <xsl:for-each select="$bookcodes">
      <xsl:if test="generate-id(.)=
                    generate-id($bookcodes[name=current()/name and
                                           code=current()/code])">
        <!--hit the first of each unique group-->
        <xsl:for-each select="$bookcodes[name=current()/name and
                                         code=current()/code][last()]">
          Last book/code in product: <xsl:value-of
                       select="concat(name,'/',code,' in ', ../name)"/>
        <xsl:text>
</xsl:text>
        </xsl:for-each>
      </xsl:if>
    </xsl:for-each>
  </xsl:for-each>
</xsl:template>

</xsl:stylesheet>
t:\ftemp>saxon mark.xml mark.xsl

Product line: Product Line 1
          Last book/code in product: Book 1/B1 in Product 2

          Last book/code in product: Book 2/B2 in Product 1

          Last book/code in product: Book 3/B3 in Product 2

          Last book/code in product: Book 4/B4 in Product 2

Product line: Product Line 2
          Last book/code in product: Book 1/B1 in Product 1

Product line: Product Line 1 (ver 2)
          Last book/code in product: Book 1/B1 in Product 2

          Last book/code in product: Book 2/B2 in Product 2

          Last book/code in product: Book 5/B5 in Product 1

          Last book/code in product: Book 3/B3 in Product 2

          Last book/code in product: Book 4/B4 in Product 2

t:\ftemp>rem Done!



--
World-wide on-site corporate, govt. & user group XML/XSL training.
G. Ken Holman                 mailto:gkholman(_at_)CraneSoftwrights(_dot_)com
Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/s/
Box 266, Kars, Ontario CANADA K0A-2E0    +1(613)489-0999 (F:-0995)
Male Breast Cancer Awareness  http://www.CraneSoftwrights.com/s/bc
Legal business disclaimers:  http://www.CraneSoftwrights.com/legal



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