[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

RE: GROUPING AND KEYS

Subject: RE: GROUPING AND KEYS
From: Cleyton Jordan <cleytonjordan@xxxxxxxxxxx>
Date: Wed, 29 Apr 2009 03:25:14 -0700 (PDT)
RE:  GROUPING AND KEYS
Hi Michael,

I would like to thank you for your explanation. It was brillant.

So this bit of code will output only one value when they are the same.

<xsl:for-each select="foo/shift/partNo[count(. | key('partNo', @num)[=
1]) = 1]">

And this bit will output all values.

 <xsl:for-each select="key('partNo', @num)">

It is a like a one to many relationship or header / values.

Cheers

C


--- On Wed, 29/4/09, xsl-list-digest-help@xxxxxxxxxxxxxxxxxxxxxx
<xsl-list-digest-help@xxxxxxxxxxxxxxxxxxxxxx> wrote:

> From: xsl-list-digest-help@xxxxxxxxxxxxxxxxxxxxxx
<xsl-list-digest-help@xxxxxxxxxxxxxxxxxxxxxx>
> Subject: xsl-list Digest 29 Apr 2009 05:10:00 -0000 Issue 1832
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Date: Wednesday, 29 April, 2009, 6:10 AM
> xsl-list Digest 29 Apr 2009 05:10:00 -0000 Issue 1832
>
> Topics (messages 50662 through 50668):
>
> GROUPING AND KEYS
> 	50662 by: Cleyton Jordan
> 	50663 by: Michael Kay
>
> Re: How to cast current-group() ?
> 	50664 by: Studer Leo
> 	50665 by: David Carlisle
> 	50666 by: Studer Leo
>
> Placing an element in a very specific position
> 	50667 by: Anders.Svensson.sorman.com
> 	50668 by: G. Ken Holman
>
> Administrivia:
>
> To subscribe to the digest, e-mail:
> 	<xsl-list-digest-subscribe@xxxxxxxxxxxxxxxxxxxxxx>
>
> To unsubscribe from the digest, e-mail:
> 	<xsl-list-digest-unsubscribe@xxxxxxxxxxxxxxxxxxxxxx>
>
> To post to the list, e-mail:
> 	<xsl-list@xxxxxxxxxxxxxxxxxxxxxx>
>
>
> ----------------------------------------------------------------------
> Date: Tue, 28 Apr 2009 03:21:09 -0700 (PDT)
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> From: Cleyton Jordan <cleytonjordan@xxxxxxxxxxx>
> Subject: GROUPING AND KEYS
> Message-ID:
> <723360.94134.qm@xxxxxxxxxxxxxxxxxxxxxxxxxxx>
>
> Hi,
>
> I would like to understand how keys and grouping work in
> XSLT and I came ac=
> ross a post that might help me. However, I have some
> questions regarding th=
> e code and would appreciate if someone could shed some
> light about sections=
>  of the code I do not understand.
>
> "I have Nodes that all have "Shift" data.
> Within these Shifts, I have a Pa=
> rt Number.  Now, I want to be able to group and add
> together all the data a=
> ssociated with a Part Number, regardless of what Shift it
> was produced in.=
> =20
>
> For example, I want to be able to add together all the
> "counts" for part nu=
> mber 1. "=20
>
> <foo>
> <shift>
>   <partNo num=3D"1">
>     <data count=3D"2"/>
>     <data time=3D"3"/>
>   </partNo>
> </shift>
> <shift>
>   <partNo num=3D"1">
>     <data count=3D"1"/>
>     <data time=3D"5"/>
>   </partNo>
> </shift>
> <shift>
>   <partNo num=3D"2">
>     <data count=3D"5"/>
>     <data time=3D"7"/>
>   </partNo>
> </shift>
> <foo>
> 1 - Is there a way to visualise in XSLT what this key looks
> like?
>
> <xsl:key name=3D"partNo"
> match=3D"partNo" use=3D"@num" />
>
> In this statement <xsl:for-each
> select=3D"foo/shift/partNo[count(. | key('p=
> artNo', @num)[1]) =3D 1]">
>
> we are selecting all partNo nodes where count(. | key(
> 'partNo', @num)[1]) =
> =3D 1]
>
> 2 - What does . mean in this expression? the partNo
> node?=20
>
> 3 - What does | mean?=20
>
> 4 - key( 'partNo', @num) - this is the key. Are we
> using the current @num a=
> ttribute to get all the partNo whose @num =3D 1 then 2
> etc...?
>
> 5 - )[1]) =3D 1 - Why is it using an array index [1] to get
> the first one a=
> nd then using =3D 1 ?
>
> I would very much appreciate some feedback and help to
> understand this code=
> ..
>
> CJ
>
> CODE
>
> <xsl:key name=3D"partNo"
> match=3D"partNo" use=3D"@num" />
>
> <xsl:template match=3D"/">
>     <xsl:for-each
> select=3D"foo/shift/partNo[count(. |
> key('partNo', @num)[=
> 1]) =3D 1]">
>         <xsl:sort select=3D"@num" />
>         Part num: <xsl:value-of
> select=3D"@num" />
>         <xsl:for-each
> select=3D"key('partNo', @num)">
>             [<xsl:value-of
> select=3D"data/@count" />,
>             <xsl:value-of
> select=3D"data/@time" />]
>         </xsl:for-each>
>         <br />
>
>     </xsl:for-each>
> </xsl:template>
> </xsl:stylesheet>=0A=0A=0A
>
> ------------------------------
>
> Date: Tue, 28 Apr 2009 11:41:57 +0100
> To: <xsl-list@xxxxxxxxxxxxxxxxxxxxxx>
> From: "Michael Kay" <mike@xxxxxxxxxxxx>
> Subject: RE:  GROUPING AND KEYS
> Message-ID:
> <5E5B62704D0144729D28C826C55063DD@Sealion>
>
> It's worth being clear that we're talking here
> about the Muenchian method of
> grouping in XSLT 1.0. Grouping in XSLT 2.0 is much much
> simpler.
>
> > 1 - Is there a way to visualise in XSLT what this key
> looks like?
> >
> > <xsl:key name="partNo"
> match="partNo" use="@num" />
>
> You can think of it like this: "Each document that
> contains partNo elements
> has an index, allowing a partNo element to be found quickly
> if the value of
> its @num attribute is known". For example,
> key('partNo', 'P123') returns all
> the partNo elements whose @num value is P123.
> >
> >
> > In this statement <xsl:for-each
> > select="foo/shift/partNo[count(. |
> key('partNo', @num)[1]) = 1]">
>
> In XSLT 1.0, there is no simple way of asking "$A is
> $B", that is, testing
> whether two expressions refer to the same node. There are
> two common
> workarounds to this:
>
> generate-id($A) = generate-id($B)
>
> which relies on the fact that if two nodes have the same
> generated ID then
> they are the same node, and
>
> count($A|$B) = 1
>
> which relies on the fact that the union of two singleton
> sets is a singleton
> only if both sets have the same member. In your example,
> this is the
> expression you are seeing.
>
> Specifically, it's selecting every partNo that is the
> first partNo with a
> given @num value. That is "." (the partNo being
> tested) is the same node as
> key('partNo', @num)[1], which is the first partNo
> with that @num value.
> >
> > we are selecting all partNo nodes where count(. | key(
>
> > 'partNo', @num)[1]) = 1]
> >
> > 2 - What does . mean in this expression? the partNo
> node?
>
> Yes, in a predicate "." refers to the node being
> tested.
> >
> > 3 - What does | mean?
>
> It's a union operator, it forms the union of two sets.
>
> Hope this helps.
>
> Michael Kay
> http://www.saxonica.com/
>
> ------------------------------
>
> Date: Tue, 28 Apr 2009 17:19:07 +0200
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> From: Studer Leo <leo.studer@xxxxxx>
> Subject: Re:  How to cast current-group() ?
> Message-id:
> <D707EA35-3AA7-42F2-8AB8-C4891670FAD7@xxxxxx>
>
> Dear Michael
>
> thank you for your input. I work with Saxon SA-9.1.0.6
> which is not to
> bad with typing and not foolish strict neither...
>
> The problem is the XSLT processor allows me to use this
> code snippet
>
>    <xsl:for-each-group select="/results/match"
> group-by="team">
>           <xsl:copy-of
> select="myfn:MakeTableRow(current-grouping-
> key(),current-group())"/>
>    </xsl:for-each-group>
>
> with the function only without the type control...
>
>      <xsl:function name="myf:MakeTableRow"
> as="schema-
> element(xhtml:tr)">
>          <xsl:param name="team"/>   <!--
> as="schema-element(res:team)"
> -->
>          <xsl:param name="matches"/>
> <!-- as="schema-
> element(res:match)*" -->
>          <tr xsl:validation="strict">
>             ...
>          </tr>
>      </xsl:function>
>
> your comment
>
> > current-grouping-key() is an atomic value, not an
> element. You could
> > construct an element and give it a type by validating
> it, but I
> > suspect
> > that's not what you want to do.
>
> is a solution to the problem, however not the most elegant
> one. Type
> casting would be nicer...
>
> I put the whole file in the end.
>
> Thanks again
> Leo
>
> <?xml version="1.0"
> encoding="ISO-8859-1"?>
> <xsl:stylesheet version="2.0"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform
> "
>      xmlns:xs="http://www.w3.org/2001/XMLSchema"
>      xmlns:res="http://results.bla"
>      xmlns:myf="http://leostuder.ch/funtions"
>
>      xmlns="http://www.w3.org/1999/xhtml"
>      xmlns:xhtml="http://www.w3.org/1999/xhtml"
> exclude-result-
> prefixes="xs res myf xhtml">
>
>      <xsl:output method="xhtml"
> encoding="ISO-8859-1" indent="yes"
>          doctype-public="-//W3C//DTD XHTML 1.0
> Strict//EN"
>
> doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd
>
> "/>
>
>      <xsl:import-schema
> namespace="http://results.bla" schema-
> location="results.xsd"/>
>
>      <xsl:import-schema
> namespace="http://www.w3.org/1999/xhtml"
>
> schema-location="http://www.w3.org/2002/08/xhtml/xhtml1-strict.xsd
>
> "/>
>
>      <xsl:function name="myf:MakeTableRow"
> as="schema-
> element(xhtml:tr)">
>          <xsl:param name="team"/>   <!--
> as="schema-element(res:team)"
> -->
>          <xsl:param name="matches"/>
> <!-- as="schema-
> element(res:match)*" -->
>          <tr xsl:validation="strict">
>              <td>
>                  <xsl:value-of
> select="$team"/>
>              </td>
>              <td>
>                  <xsl:value-of
> select="count($matches)"/>
>              </td>
>              <xsl:variable name="won"
>
> select="count($matches[res:team[.=$team]/@score  gt
> res:team[.!=$team]/@score])"
>                  as="xs:integer"/>
>              <td>
>                  <xsl:value-of
> select="$won"/>
>              </td>
>              <td>
>                  <xsl:value-of
>
> select="count($matches[res:team[.=$team]/@score
> lt res:team[.!=$team]/@score])"/>
>              </td>
>              <xsl:variable name="drawn"
>
> select="count($matches[res:team[.=$team]/@score  eq
> res:team[.!=$team]/@score])"
>                  as="xs:integer"/>
>              <td>
>                  <xsl:value-of
> select="$drawn"/>
>              </td>
>              <td>
>                  <xsl:value-of
> select="sum($matches/res:team[.=$team]/
> @score)"/>
>              </td>
>              <td>
>                  <xsl:value-of
> select="sum($matches/res:team[.!=$team]/
> @score)"/>
>              </td>
>              <td>
>                  <xsl:number
> value="3*$won+$drawn"/>
>              </td>
>          </tr>
>      </xsl:function>
>
>      <xsl:template match="/">
>          <html xsl:validation="strict">
>              <!-- xsl:validation="strict"
> possible in html tag -->
>              <head>
>                  <title>Spielresultate</title>
>              </head>
>              <body>
>                  <xsl:apply-templates/>
>              </body>
>          </html>
>      </xsl:template>
>
>      <xsl:template match="res:results">
>          <h2>Results</h2>
>
>          <table cellpadding="10">
>              <thead>
>                  <tr>
>                      <td>Team</td>
>                      <td>Played</td>
>                      <td>Won</td>
>                      <td>Lost</td>
>                      <td>Drawn</td>
>                      <td>For</td>
>                      <td>Against</td>
>                      <td>Points</td>
>                  </tr>
>              </thead>
>
>              <xsl:variable name="teamResults"
> as="schema-
> element(xhtml:tr)*">
>                  <xsl:for-each-group
> select="/res:results/res:match"
> group-by="res:team">
>                      <xsl:sequence
> select="myf:MakeTableRow(current-
> grouping-key(),current-group())"/>
>                  </xsl:for-each-group>
>              </xsl:variable>
>              <xsl:for-each
> select="$teamResults">
>                  <xsl:sort
> select="./xhtml:td[8]"
> order="descending"
> data-type="number"/>
>                  <xsl:sort
> select="./xhtml:td[6]"
> order="descending"/>
>                  <xsl:sort
> select="./xhtml:td[7]"
> order="ascending"/>
>                  <xsl:copy-of select="."/>
>              </xsl:for-each>
>
>          </table>
>
>      </xsl:template>
>
> </xsl:stylesheet>
>
> ------------------------------
>
> Date: Tue, 28 Apr 2009 16:33:47 +0100
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> From: David Carlisle <davidc@xxxxxxxxx>
> Subject: Re:  How to cast current-group() ?
> Message-Id:
> <200904281533.n3SFXlrS029185@xxxxxxxxxxxxxxxxxxx>
>
> as Michael said the problem isn't so much the schema
> typing as the fact
> that you are passing a string when the function expects an
> element.
> this fails
>  as="schema-element(res:team)"
> but so would
>     as="element()"
>
> Your function expects a team element so just give it one
> instead of a
> string, there will (presumably) necessarily be a team
> element child of
> the current node in a valid document so
>
>   <xsl:copy-of
> select="myfn:MakeTableRow(team,current-group())"/>
>
> should work and be able to cope with any typing of the
> first parameter.
>
> David
>
> ________________________________________________________________________
> The Numerical Algorithms Group Ltd is a company registered
> in England
> and Wales with company number 1249803. The registered
> office is:
> Wilkinson House, Jordan Hill Road, Oxford OX2 8DR, United
> Kingdom.
>
> This e-mail has been scanned for all viruses by Star. The
> service is
> powered by MessageLabs.
> ________________________________________________________________________
>
> ------------------------------
>
> Date: Tue, 28 Apr 2009 18:55:37 +0200
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> From: Studer Leo <leo.studer@xxxxxx>
> Subject: Re:  How to cast current-group() ?
> Message-id:
> <0DAFB6BC-B67E-4160-A896-9EEA5657A620@xxxxxx>
>
> David
>
> thanks for caring!
>
> > as Michael said the problem isn't so much the
> schema typing as the
> > fact
> > that you are passing a string when the function
> expects an element.
>
> Finally I get it. current-grouping-key() is
> xs:anyAtomicType and not
> en element...
>
> blessings
> Leo
>
> ------------------------------
>
> Date: Wed, 29 Apr 2009 00:42:25 +0200
> To: <xsl-list@xxxxxxxxxxxxxxxxxxxxxx>
> From: <Anders.Svensson@xxxxxxxxxx>
> Subject: Placing an element in a very specific position
> Message-ID:
> <D69E5A9D77766E43ADB213473C2F82BB02AE9AE1@xxxxxxxxxxxx>
> Keywords: disclaimer
>
> Hi,=20
>
> I have a problem where I have been asked if I can put an
> element in the
> top of the third column in a three-column page. My initial
> thought is
> that this can't be done. I have tried to investigate
> absolute-positioning and floats, but cannot find anything
> that would
> seem to do this. I have no idea how it would be possible to
> decide that
> it should end up in the top of the third column
> specifically. In the
> first column would be easy, and if I could put it in the
> header that
> should be easy too, but unfortunately the header is not an
> option due to
> the fact that there are space requirements so that each
> column needs to
> be utilized completely.=20
>
> Is there any way to do this, or do I need to tell my client
> that it
> can't be done?=20
>
> Any suggestions greatly appreciated!=20
>
> Regards,=20
>
> Anders
> ###########################################=0A=
> =0A=
> This message has been scanned by F-Secure Anti-Virus for
> Microsoft =
> Exchange.=0A=
> For more information, connect to http://www.f-secure.com/
>
> ------------------------------
>
> Date: Tue, 28 Apr 2009 20:39:59 -0400
> To: <xsl-list@xxxxxxxxxxxxxxxxxxxxxx>
> From: "G. Ken Holman"
> <gkholman@xxxxxxxxxxxxxxxxxxxx>
> Subject: Re:  Placing an element in a very specific
> position
> Message-Id:
> <7.0.1.0.2.20090428202827.02505178@xxxxxxxxxxxxxxxxxxxxxx>
>
> I regret to confirm your suspicions, unless perhaps there
> is an out
> that you have not described.
>
> The column geometry in XSL-FO does not allow you to key out
> a hole at
> the top of the third column and flow around it.
>
> But, I can give you a fixed size box at the top of what
> looks like
> the third column, into which you flow your element.  But
> the box
> cannot grow, so I don't know if you can use it.
>
> And you have to use XSL-FO 1.1.
>
> Create three body regions, each with one column (or two
> body regions,
> the first with two columns and the second with one column).
>  Create a
> flow map such that the region on the right flows after the
> other.
>
> Size this right-most body region shorter than the other,
> leaving the
> hole at the top.  This gives the appearance of a third
> column when,
> technically, it is a different region.
>
> Into this hole you can place an absolutely-positioned block
>
> container.  If this is only on the first page, then your
> absolutely-positioned block container can be flowed at the
> start of
> the flow.  If this is on every page then you can flow that
> absolutely-positioned block container in one of the static
> content
> areas.  Whether the content in that hole changes or not
> might be an
> issue, but you may be able to use markers to make it vary.
>
> I hope this helps!
>
> . . . . . . . . . . . Ken
>
> p.s. if Mats Hultemark is still with Sorman, please pass on
> my
> regards (but I know it is a big company and you may not
> know him).
>
> At 2009-04-29 00:42 +0200, Anders.Svensson@xxxxxxxxxx
> wrote:
> >Hi,
> >
> >I have a problem where I have been asked if I can put
> an element in the
> >top of the third column in a three-column page. My
> initial thought is
> >that this can't be done. I have tried to
> investigate
> >absolute-positioning and floats, but cannot find
> anything that would
> >seem to do this. I have no idea how it would be
> possible to decide that
> >it should end up in the top of the third column
> specifically. In the
> >first column would be easy, and if I could put it in
> the header that
> >should be easy too, but unfortunately the header is not
> an option due to
> >the fact that there are space requirements so that each
> column needs to
> >be utilized completely.
> >
> >Is there any way to do this, or do I need to tell my
> client that it
> >can't be done?
> >
> >Any suggestions greatly appreciated!
> >
> >Regards,
> >
> >Anders
>
> --
> XSLT/XSL-FO/XQuery hands-on training - Los Angeles, USA
> 2009-06-08
> Crane Softwrights Ltd.
> http://www.CraneSoftwrights.com/s/
> Training tools: Comprehensive interactive XSLT/XPath
> 1.0/2.0 video
> Video lesson:
> http://www.youtube.com/watch?v=PrNjJCh7Ppg&fmt=18
> Video overview:
> http://www.youtube.com/watch?v=VTiodiij6gE&fmt=18
> G. Ken Holman
> mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
> Male Cancer Awareness Nov'07
> http://www.CraneSoftwrights.com/s/bc
> Legal business disclaimers:
> http://www.CraneSoftwrights.com/legal
>
> ------------------------------
>
> End of xsl-list Digest
> ***********************************

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.