Help Grouping/Counting XSLT

G

Graham

Hi,
I am having trouble getting XSL to count the members of a group. What
I am trying to do is group by <objectid.Contactid> and count the
number of <activityid>'s for each <objectid.contactid>. My XSL keeps
returning zero for the count. The results for the XML/XSLT files below
should look like:-


Contact # of Visits Account
----------------------------------------------------------
johnson, johnny 2 account 1 sub
bragg, billy 1 account2


Any help would be greatly appreciated.

Thanks
Graham

XML
---

<resultset>
<result>
<activityid>{88320F75-4C77-4750-9E3F-C3991210941E}</activityid>
<ownerid name="Admin, Sys" dsc="0"
type="8">{31157DA0-9F83-4495-B91A-A3EB012F84A3}</ownerid>
<owninguser>{31157DA0-9F83-4495-B91A-A3EB012F84A3}</owninguser>
<objectid.contactid>{BC2119B2-3BD6-4B86-8D3C-26738ABD63B5}</objectid.contactid>
<objectid.fullname>johnson, johnny</objectid.fullname>
<objectid.accountid name="account 1 sub"
dsc="0">{FD5180B0-D7D8-45A4-8665-34A2807D2F3D}</objectid.accountid>
</result>
<result>
<activityid>{368CCF74-559C-450F-8DD4-23646DDB0787}</activityid>
<ownerid name="Admin, Sys" dsc="0"
type="8">{31157DA0-9F83-4495-B91A-A3EB012F84A3}</ownerid>
<owninguser>{31157DA0-9F83-4495-B91A-A3EB012F84A3}</owninguser>
<objectid.contactid>{BC2119B2-3BD6-4B86-8D3C-26738ABD63B5}</objectid.contactid>
<objectid.fullname>johnson, johnny</objectid.fullname>
<objectid.accountid name="account 1 sub"
dsc="0">{FD5180B0-D7D8-45A4-8665-34A2807D2F3D}</objectid.accountid>
</result>
<result>
<activityid>{368CCF74-559C-450F-8DD4-23646DDX0787}</activityid>
<ownerid name="Admin, Sys" dsc="0"
type="8">{31157DA0-9F83-4495-B91A-A3EB012F84A3}</ownerid>
<owninguser>{31157DA0-9F83-4495-B91A-A3EB012F84A3}</owninguser>
<objectid.contactid>{4FC6C984-6890-424E-9A73-30A5BA083422}</objectid.contactid>
<objectid.fullname>bragg, billy</objectid.fullname>
<objectid.accountid name="account2"
dsc="0">{FG5180B0-D7D8-45A4-8665-34A2807D2F3D}</objectid.accountid>
</result>
</resultset>



XSLT
-----

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<!-- Define keys used to group elements -->
<xsl:key name="keyContactGUID" match="result" use="objectid.contactid"
/>

<xsl:template match="/">

<html>
<body>
<h2>Grouping Test</h2>

<table border="1">
<tr bgcolor="#9acd32">
<th>Contact</th>
<th># of Visits</th>
<th>Account</th>
</tr>

<xsl:variable name="countID" select="0"></xsl:variable>

<!-- Process each Contact-->
<xsl:for-each select="//result[generate-id(.) =
generate-id(key('keyContactGUID',objectid.contactid)[1])]">
<tr>

<xsl:variable name="CID"><xsl:value-of
select="objectid.contactid" /></xsl:variable>
<td><xsl:value-of
select="objectid.fullname"></xsl:value-of><p></p></td>
<td> <xsl:value-of
select="count(activityid[@CID=current()])"></xsl:value-of></td>
<td><xsl:value-of
select="objectid.accountid/@name"></xsl:value-of></td>
</tr>

</xsl:for-each>

</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
 
M

Marrow

Hi Graham,

If you look again at the line (sometimes it just takes another set of
eyes)...

<xsl:value-of select="count(activityid[@CID=current()])"></xsl:value-of>

you are using '@CID' - but as I can't see an attributes at all called 'CID'
I'm assuming rather than '@' you want '$' so you refer to the variable of
that name.

If you correct it use the variable...
<xsl:value-of select="count(activityid[$CID =
current()])"></xsl:value-of>
it still won't give you what you want - because current() inside a predicate
[] refers to the current context node at this point - not the current node
being tested by the predicate [].

If you correct that to...
<xsl:value-of select="count(activityid[. = $CID])"></xsl:value-of>
you are still not getting what you want - as there doesn't seem to be any
<activityid>'s that match a <objectid.contactid> within a <result>

So, remember when doing Muenchian grouping two things...
1) the grouping select returns only the first intance of the distinct (not
all of them)
2) having defined a key - re-use that key to find everything within the
current (or given) group

So you want something like...
<xsl:value-of
select="count(key('keyContactGUID',objectid.contactid)/activityid)"/>


HTH
Marrow
http://www.marrowsoft.com - home of Xselerator (XSLT IDE and debugger)
http://www.topxml.com/Xselerator










Graham said:
Hi,
I am having trouble getting XSL to count the members of a group. What
I am trying to do is group by <objectid.Contactid> and count the
number of <activityid>'s for each <objectid.contactid>. My XSL keeps
returning zero for the count. The results for the XML/XSLT files below
should look like:-


Contact # of Visits Account
----------------------------------------------------------
johnson, johnny 2 account 1 sub
bragg, billy 1 account2


Any help would be greatly appreciated.

Thanks
Graham

XML
---

<resultset>
<result>
<activityid>{88320F75-4C77-4750-9E3F-C3991210941E}</activityid>
<ownerid name="Admin, Sys" dsc="0"
type="8">{31157DA0-9F83-4495-B91A-A3EB012F84A3}</ownerid>
<owninguser>{31157DA0-9F83-4495-B91A-A3EB012F84A3}</owninguser>
<objectid.fullname>johnson, johnny</objectid.fullname>
<objectid.accountid name="account 1 sub"
dsc="0">{FD5180B0-D7D8-45A4-8665-34A2807D2F3D}</objectid.accountid>
</result>
<result>
<activityid>{368CCF74-559C-450F-8DD4-23646DDB0787}</activityid>
<ownerid name="Admin, Sys" dsc="0"
type="8">{31157DA0-9F83-4495-B91A-A3EB012F84A3}</ownerid>
<owninguser>{31157DA0-9F83-4495-B91A-A3EB012F84A3}</owninguser>
<objectid.fullname>johnson, johnny</objectid.fullname>
<objectid.accountid name="account 1 sub"
dsc="0">{FD5180B0-D7D8-45A4-8665-34A2807D2F3D}</objectid.accountid>
</result>
<result>
<activityid>{368CCF74-559C-450F-8DD4-23646DDX0787}</activityid>
<ownerid name="Admin, Sys" dsc="0"
type="8">{31157DA0-9F83-4495-B91A-A3EB012F84A3}</ownerid>
<owninguser>{31157DA0-9F83-4495-B91A-A3EB012F84A3}</owninguser>
<objectid.fullname>bragg, billy</objectid.fullname>
<objectid.accountid name="account2"
dsc="0">{FG5180B0-D7D8-45A4-8665-34A2807D2F3D}</objectid.accountid>
</result>
</resultset>



XSLT
-----

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<!-- Define keys used to group elements -->
<xsl:key name="keyContactGUID" match="result" use="objectid.contactid"
/>

<xsl:template match="/">

<html>
<body>
<h2>Grouping Test</h2>

<table border="1">
<tr bgcolor="#9acd32">
<th>Contact</th>
<th># of Visits</th>
<th>Account</th>
</tr>

<xsl:variable name="countID" select="0"></xsl:variable>

<!-- Process each Contact-->
<xsl:for-each select="//result[generate-id(.) =
generate-id(key('keyContactGUID',objectid.contactid)[1])]">
<tr>

<xsl:variable name="CID"><xsl:value-of
select="objectid.contactid" /></xsl:variable>
<td><xsl:value-of
select="objectid.fullname"></xsl:value-of><p></p></td>
<td> <xsl:value-of
select="count(activityid[@CID=current()])"></xsl:value-of></td>
<td><xsl:value-of
select="objectid.accountid/@name"></xsl:value-of></td>
</tr>

</xsl:for-each>

</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
 
M

Marrow

Hi Graham,

If you look again at the line (sometimes it just takes another set of
eyes)...

<xsl:value-of select="count(activityid[@CID=current()])"></xsl:value-of>

you are using '@CID' - but as I can't see an attributes at all called 'CID'
I'm assuming rather than '@' you want '$' so you refer to the variable of
that name.

If you correct it use the variable...
<xsl:value-of select="count(activityid[$CID =
current()])"></xsl:value-of>
it still won't give you what you want - because current() inside a predicate
[] refers to the current context node at this point - not the current node
being tested by the predicate [].

If you correct that to...
<xsl:value-of select="count(activityid[. = $CID])"></xsl:value-of>
you are still not getting what you want - as there doesn't seem to be any
<activityid>'s that match a <objectid.contactid> within a <result>

So, remember when doing Muenchian grouping two things...
1) the grouping select returns only the first intance of the distinct (not
all of them)
2) having defined a key - re-use that key to find everything within the
current (or given) group

So you want something like...
<xsl:value-of
select="count(key('keyContactGUID',objectid.contactid)/activityid)"/>


HTH
Marrow
http://www.marrowsoft.com - home of Xselerator (XSLT IDE and debugger)
http://www.topxml.com/Xselerator










Graham said:
Hi,
I am having trouble getting XSL to count the members of a group. What
I am trying to do is group by <objectid.Contactid> and count the
number of <activityid>'s for each <objectid.contactid>. My XSL keeps
returning zero for the count. The results for the XML/XSLT files below
should look like:-


Contact # of Visits Account
----------------------------------------------------------
johnson, johnny 2 account 1 sub
bragg, billy 1 account2


Any help would be greatly appreciated.

Thanks
Graham

XML
---

<resultset>
<result>
<activityid>{88320F75-4C77-4750-9E3F-C3991210941E}</activityid>
<ownerid name="Admin, Sys" dsc="0"
type="8">{31157DA0-9F83-4495-B91A-A3EB012F84A3}</ownerid>
<owninguser>{31157DA0-9F83-4495-B91A-A3EB012F84A3}</owninguser>
<objectid.fullname>johnson, johnny</objectid.fullname>
<objectid.accountid name="account 1 sub"
dsc="0">{FD5180B0-D7D8-45A4-8665-34A2807D2F3D}</objectid.accountid>
</result>
<result>
<activityid>{368CCF74-559C-450F-8DD4-23646DDB0787}</activityid>
<ownerid name="Admin, Sys" dsc="0"
type="8">{31157DA0-9F83-4495-B91A-A3EB012F84A3}</ownerid>
<owninguser>{31157DA0-9F83-4495-B91A-A3EB012F84A3}</owninguser>
<objectid.fullname>johnson, johnny</objectid.fullname>
<objectid.accountid name="account 1 sub"
dsc="0">{FD5180B0-D7D8-45A4-8665-34A2807D2F3D}</objectid.accountid>
</result>
<result>
<activityid>{368CCF74-559C-450F-8DD4-23646DDX0787}</activityid>
<ownerid name="Admin, Sys" dsc="0"
type="8">{31157DA0-9F83-4495-B91A-A3EB012F84A3}</ownerid>
<owninguser>{31157DA0-9F83-4495-B91A-A3EB012F84A3}</owninguser>
<objectid.fullname>bragg, billy</objectid.fullname>
<objectid.accountid name="account2"
dsc="0">{FG5180B0-D7D8-45A4-8665-34A2807D2F3D}</objectid.accountid>
</result>
</resultset>



XSLT
-----

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<!-- Define keys used to group elements -->
<xsl:key name="keyContactGUID" match="result" use="objectid.contactid"
/>

<xsl:template match="/">

<html>
<body>
<h2>Grouping Test</h2>

<table border="1">
<tr bgcolor="#9acd32">
<th>Contact</th>
<th># of Visits</th>
<th>Account</th>
</tr>

<xsl:variable name="countID" select="0"></xsl:variable>

<!-- Process each Contact-->
<xsl:for-each select="//result[generate-id(.) =
generate-id(key('keyContactGUID',objectid.contactid)[1])]">
<tr>

<xsl:variable name="CID"><xsl:value-of
select="objectid.contactid" /></xsl:variable>
<td><xsl:value-of
select="objectid.fullname"></xsl:value-of><p></p></td>
<td> <xsl:value-of
select="count(activityid[@CID=current()])"></xsl:value-of></td>
<td><xsl:value-of
select="objectid.accountid/@name"></xsl:value-of></td>
</tr>

</xsl:for-each>

</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
 
?

=?ISO-8859-1?Q?J=FCrgen_Kahrs?=

Graham said:
I am having trouble getting XSL to count the members of a group. What
I am trying to do is group by <objectid.Contactid> and count the
number of <activityid>'s for each <objectid.contactid>. My XSL keeps
returning zero for the count. The results for the XML/XSLT files below
should look like:-

If you should ever consider using xmlgawk, here is
a solution in xmlgawk (tested):

BEGIN { XMLMODE=1 }

XMLSTARTELEM {
prev=XMLSTARTELEM
if (XMLSTARTELEM=="objectid.accountid")
na=XMLATTR["name"]
}

XMLCHARDATA {
if (prev=="objectid.contactid")
id=$0
if (prev=="objectid.fullname")
fn=$0
if (prev=="objectid.accountid")
ac=$0
prev=""
}

XMLENDELEM == "result" {
name[id] = na
full[id] = fn
count[id] ++
account[id] = ac
}

END {
for (id in count)
print full[id] "\t\t" count[id] "\t\t" name[id]
}

The result I get is:

bragg, billy 1 account2
johnson, johnny 2 account 1 sub


Almost what you wanted:
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top