Help Grouping/Counting XSLT

Discussion in 'XML' started by Graham, Sep 17, 2004.

  1. Graham

    Graham Guest

    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>
    Graham, Sep 17, 2004
    #1
    1. Advertising

  2. Graham

    Marrow Guest

    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" <> wrote in message
    news:...
    > 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.contact
    id>
    > <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.contact
    id>
    > <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.contact
    id>
    > <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>
    Marrow, Sep 17, 2004
    #2
    1. Advertising

  3. Graham

    Marrow Guest

    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" <> wrote in message
    news:...
    > 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.contact
    id>
    > <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.contact
    id>
    > <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.contact
    id>
    > <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>
    Marrow, Sep 17, 2004
    #3
  4. Graham wrote:

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


    > Contact # of Visits Account
    > ----------------------------------------------------------
    > johnson, johnny 2 account 1 sub
    > bragg, billy 1 account2
    =?ISO-8859-1?Q?J=FCrgen_Kahrs?=, Sep 17, 2004
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Christian Ludwig

    XSLT: sorting and grouping

    Christian Ludwig, Nov 24, 2003, in forum: XML
    Replies:
    2
    Views:
    602
    Christian Ludwig
    Nov 26, 2003
  2. Per Jørgen Vigdal

    Help on xslt - grouping

    Per Jørgen Vigdal, May 19, 2005, in forum: XML
    Replies:
    6
    Views:
    485
    Dimitre Novatchev
    May 20, 2005
  3. Mark
    Replies:
    1
    Views:
    401
    Janwillem Borleffs
    Aug 18, 2005
  4. John Galenski

    XSLT Grouping and Counting Question

    John Galenski, Feb 6, 2009, in forum: XML
    Replies:
    1
    Views:
    1,921
    Martin Honnen
    Feb 6, 2009
  5. edwardfredriks

    counting up instead of counting down

    edwardfredriks, Sep 6, 2005, in forum: Javascript
    Replies:
    6
    Views:
    197
    Dr John Stockton
    Sep 7, 2005
Loading...

Share This Page