xsl-list
[Top] [All Lists]

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

2008-02-01 11:39:30
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[(_at_)*[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(_dot_)james(_at_)gmail(_dot_)com] 
Sent: 01 February 2008 18:07
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: Re: [xsl] 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(_at_)saxonica(_dot_)com> wrote:
Looks to me something like this:

<xsl:variable name="pop" select="collection('...')//*[(_at_)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()[(_at_)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(_dot_)james(_at_)gmail(_dot_)com]
Sent: 01 February 2008 17:23
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: [xsl] 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[(_at_)type='blort'])</cell>
<cell><xsl:value-of select="count(.//seg[(_at_)type='foo'])</cell>
<cell><xsl:value-of select="count(.//seg[(_at_)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



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




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



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



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