[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Counting common value within specific attributes


Subject: Re: [xsl] Counting common value within specific attributes
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Fri, 28 Apr 2006 03:57:35 -0400

At 2006-04-28 12:40 +1000, Andrew Quan wrote:
I'm Using XSLT 1.0

Your solution can be handled easily with pure XSLT 1.0 without extensions.


I've searched around in the FAQ and i couldnt find any information regarding
this issue - hopefully I can get some help, although I feel like I may have
not structured my question correctly... I hope you understand it. I'm a
relative beginner too, so that probably doesnt help either. Sorry!

I could not tell from your question if you knew the unique channel values in advance, or if you had to determine them.


Given a data set similar to this:
...
Is there a way to count how many times, for example, a 2 appears in all
attributes starting with the name "chan"?

Do you know "2" before hand? Then it is a simple count.


If you do not know the unique values before hand, then you have to determine them.

Below is two solutions. Solution quan1.xsl is where you know the channel values ahead of time. Solution quan2.xsl is where you do not know the values and have to determine them from the data. This involves determining the unique values across the entire data set and then comparing against them for each device.

I hope this helps.

. . . . . . . . . . Ken

T:\ftemp>type quan.xml
<?xml version="1.0" encoding="US-ASCII"?>
<devices>
<device>
    <deviceID>1</deviceID>
    <desc>Description1</desc>
    <chan1>0</chan1>
    <chan2>0</chan2>
    <chan3>2</chan3>
    <chan4>2</chan4>
    <chan5>2</chan5>
    <chan6>2</chan6>
    <chan7>4</chan7>
    <chan8>0</chan8>
    <chan9>2</chan9>
</device>
<device>
    <deviceID>2</deviceID>
    <desc>Description2</desc>
    <chan1>2</chan1>
    <chan2>2</chan2>
    <chan3>2</chan3>
    <chan4>4</chan4>
    <chan5>2</chan5>
    <chan6>2</chan6>
    <chan7>2</chan7>
    <chan8>2</chan8>
    <chan9>4</chan9>
</device>
</devices>
T:\ftemp>type quan1.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">

<xsl:output method="text"/>

<xsl:template match="devices">
Device ID | Description | Channels=0 | Channels=2 | Channels=4 |
<xsl:for-each select="device">
  <xsl:variable name="channels"
                select="*[starts-with(local-name(.),'chan')]"/>
  <xsl:value-of select="concat( deviceID,' | ',desc, ' | ',
                        count( $channels[ .= 0 ] ),' | ',
                        count( $channels[ .= 2 ] ),' | ',
                        count( $channels[ .= 4 ] ),' | ')"/>
  <xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>

</xsl:stylesheet>
T:\ftemp>call xslt quan.xml quan1.xsl quan1.txt

T:\ftemp>type quan1.txt

Device ID | Description | Channels=0 | Channels=2 | Channels=4 |
1 | Description1 | 3 | 5 | 1 |
2 | Description2 | 0 | 7 | 2 |

T:\ftemp>type quan2.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">

<xsl:output method="text"/>

<!--determine unique channels-->
<xsl:key name="channels" match="*[starts-with(local-name(.),'chan')]" use="."/>
<xsl:variable name="channels"
              select="//*[starts-with(local-name(.),'chan')]
                      [generate-id(.)=generate-id(key('channels',.)[1])]"/>

<!--process all devices-->
<xsl:template match="devices">
  <!--header based on unique channels across all devices-->
  <xsl:text>Device ID | Description | </xsl:text>
  <xsl:for-each select="$channels">
    <xsl:text/>Channel <xsl:value-of select="."/> | <xsl:text/>
  </xsl:for-each>
  <xsl:text>
</xsl:text>
  <!--report each device-->
  <xsl:for-each select="device">
    <xsl:variable name="device-channels"
                  select="*[starts-with(local-name(.),'chan')]"/>
    <xsl:value-of select="concat( deviceID,' | ',desc, ' | ')"/>
    <!--report each channel for each device-->
    <xsl:for-each select="$channels">
      <xsl:value-of select="concat( count( $device-channels[ .= current() ] ),
                                    ' | ' )"/>
    </xsl:for-each>
    <xsl:text>
</xsl:text>
  </xsl:for-each>
</xsl:template>

</xsl:stylesheet>
T:\ftemp>call xslt quan.xml quan2.xsl quan2.txt

T:\ftemp>type quan2.txt
Device ID | Description | Channel 0 | Channel 2 | Channel 4 |
1 | Description1 | 3 | 5 | 1 |
2 | Description2 | 0 | 7 | 2 |



--
Registration open for XSLT/XSL-FO training: Wash.,DC 2006-06-12/16
Also for XSLT/XSL-FO training:    Minneapolis, MN 2006-07-31/08-04
Also for XML/XSLT/XSL-FO training:Birmingham,England 2006-05-22/25
Also for XSLT/XSL-FO training:    Copenhagen,Denmark 2006-05-08/11
World-wide on-site corporate, govt. & user group XML/XSL training.
G. Ken Holman                 mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/s/
Box 266, Kars, Ontario CANADA K0A-2E0    +1(613)489-0999 (F:-0995)
Male Cancer Awareness Aug'05  http://www.CraneSoftwrights.com/s/bc
Legal business disclaimers:  http://www.CraneSoftwrights.com/legal


Current Thread
Keywords