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

RE: XSLT2, collection(), and xsl:key

Subject: RE: XSLT2, collection(), and xsl:key
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Fri, 1 Feb 2008 18:39:00 -0000
RE:  XSLT2
OK, I misunderstood. I thought that's what you meant by doing it manually,
and that that wasn't what you wanted to do.

To make it data-driven like this, you get rid of the outer
xsl:for-each-group and replace it with an <xsl:for-each select="table">, and
then you do something like

<xsl:variable name="table" select="."/>
<xsl:variable name="pop"
select="collection('...')//*[name()=$table/@element[@*[name()=$table/@att]]]
"/>

and then 

<xsl:variable name="types"
select="distinct-values($pop/@*[name()=$table/@att)"/>

Michael Kay
http://www.saxonica.com/

> -----Original Message-----
> From: James Cummings [mailto:cummings.james@xxxxxxxxx] 
> Sent: 01 February 2008 18:07
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: Re:  XSLT2, collection(), and xsl:key
> 
> Hi again,
> 
> I must be missing something (I usually am), if I'm reading 
> this (and Andrew's grouping in a variable version), they both 
> apply to all elements, and here all elements with only a 
> @type.  Part of my problem is that I definitely *don't* want 
> to do all elements, and in some cases more than one attribute 
> on some elements.  So I really need to feed it a list of 
> element/@attrib rather than just do everything matching a pattern.
> 
> I mean I could build a list in the xslt in a variable something like:
> <xsl:variable name="tables">
> <table element="seg" att="type"/>
> <table element="seg" att="sub-type"/>
> <table element="other" att="type"/>
> <table element="thing" att="name"/>
> <!-- etc -->
> </xsl:variable>
> 
> And then try the grouping selecting each $tables/table ?  
> Would that work?
> 
> -James
> 
> On Feb 1, 2008 5:45 PM, Michael Kay <mike@xxxxxxxxxxxx> wrote:
> > Looks to me something like this:
> >
> > <xsl:variable name="pop" select="collection('...')//*[@type]"/>
> >
> > <xsl:for-each-group select="$pop" group-by="node-name(.)">
> >   <h1><xsl:value-of select="current-grouping-key()"/></h1>
> >   <table>
> >     <tr>
> >       <td>document</td>
> >       <xsl:variable name="types"
> > select="distinct-values(current-group()/@type)"/>
> >       <xsl:for-each select="$types">
> >         <td><xsl:value-of select="."/></td>
> >       </xsl:for-each>
> >     </tr>
> >     <xsl:for-each-group select="current-group()"
> > group-by="ancestor::p/@xml:id">
> >     <tr>
> >       <td><xsl:value-of select="current-grouping-key()"/></td>
> >       <xsl:for-each select="$types">
> >         <td><xsl:value-of
> > select="count(current-group()[@type=current()])"/></td>
> >       </xsl:for-each>
> >     </tr>
> >   </table>
> > </xsl:for-each-group>
> >
> > Michael Kay
> > http://www.saxonica.com/
> >
> >
> > > -----Original Message-----
> > > From: James Cummings [mailto:cummings.james@xxxxxxxxx]
> > > Sent: 01 February 2008 17:23
> > > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> > > Subject:  XSLT2, collection(), and xsl:key
> > >
> > > Hiya,
> > >
> > > I'm using the collection() function and Saxon to produce some 
> > > statistics about how many of which elements of which type in a 
> > > particular set of documents.
> > >
> > > Let's say that document one has something like:
> > >
> > > <p xml:id="doc1" type="hypothetical"> There is some text 
> with <seg 
> > > type="foo">some foo</seg> and occasionally <seg 
> > > type="blort">blort</seg> and <other 
> type="wibble">wibble</other></p>
> > >
> > >
> > > and document two (and up to some really large number) is like:
> > >
> > > <p xml:id="doc2">
> > > There is another doc with <seg type="foo">some foo</seg> and 
> > > occasionally <seg type="notBlort">notBlort</seg> and <other 
> > > type="fluffy">fluffy other</other> and <some
> > >   name="thing">someThing</some></p>
> > >
> > > What I want to produce are tables of counts of specific 
> elements, by 
> > > document and type. So something like the following (though using 
> > > table/row/cell xml markup):
> > >
> > >
> > > table: other
> > > document | fluffy | wibble | stuff
> > > doc1 | 0 | 1 | 0
> > > doc2 | 1 | 0 | 0
> > > doc3 | 20 | 12 | 54
> > >
> > > table: seg
> > > document | blort | foo | notBlort
> > > doc1 | 1 | 1 | 0
> > > doc2 | 0 | 1| 1
> > > doc3 | 23 | 44 | 58
> > >
> > > table: some
> > > document | thing | else | now
> > > doc1 | 0 | 0 | 0
> > > doc2 | 1 | 0 | 0
> > > doc3 | 12 | 5 | 24
> > >
> > > I can build this manually (and for one element I have done
> > > so) by doing:
> > >
> > > <xsl:variable name="docs"
> > > select="collection('../../working/xml/docs.xml')"/>
> > > <xsl:template name="main">
> > > <table><head>seg by type</head>
> > > <row rend="label">
> > > <cell>document</cell>
> > > <cell>blort</cell>
> > > <cell>foo</cell>
> > > <cell>notBlort</cell>
> > > </row>
> > > <xsl:for-each select="$docs//p"> <!-- let's pretend p is the root 
> > > element --> <row> <xsl:variable name="doc"
> > > select="@xml:id"/> <cell><xsl:value-of select="$doc"/></cell> 
> > > <cell><xsl:value-of select="count(.//seg[@type='blort'])</cell>
> > > <cell><xsl:value-of select="count(.//seg[@type='foo'])</cell>
> > > <cell><xsl:value-of select="count(.//seg[@type='notBlort'])</cell>
> > > </row>
> > > </xsl:for-each>
> > > </table>
> > > </xsl:template>
> > >
> > > But that isn't really the point now is it?  I tried to 
> use <xsl:key> 
> > > but I ran into the problem of it not liking the
> > > collection() function as part of the match.
> > >
> > > What I want to do is be able to say for-each doc, build 
> me a table 
> > > of all the (let's pretend unknown) values of this 
> attribute on this 
> > > element.  So something like:
> > >
> > > <xsl:for-each select="$docs//p">
> > > <xsl:value-of select="my:function(other/@type, seg/@type, 
> > > thing/@name, new/@type)"/> </xsl:for-each>
> > >
> > > and without knowing the values of @type in advance it 
> makes a table 
> > > like above of them (using distinct-values()?) and counting their 
> > > occurrences.
> > >
> > > This is a case where I know it must be possible, and I 
> could just go 
> > > and do it manually, (in reality there are about 10 
> elements with a 
> > > number of attributes, with around 20 values each), but it 
> just seems
> > > *wrong* to do it that way. ;-)
> > >
> > > Suggestions?
> > >
> > > Thanks,
> > >
> > > -James

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-2007 All Rights Reserved.