xsl-list
[Top] [All Lists]

Re: [xsl] Counting common value within specific attributes

2006-04-27 22:22:04
Hi Andrew,
  Your XML was not well formed. So I changed it to this for testing

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

I think you cannot solve this problem with pure XSLT 1.0. You need to
use node-set extension function. And a grouping technique like
Muenchian method as used in this stylesheet.

Below is the solution to this problem

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                       xmlns:common="http://exslt.org/common";
                       exclude-result-prefixes="common"
                       version="1.0">

<xsl:output method="html" />

<xsl:key name="by-chan" match="*[starts-with(name(),'chan')]" use="." />

<xsl:template match="/">
  <html>
    <head>
      <title/>
    </head>
    <body>
    <table>
      <th>
        <td>Device ID</td><td>Description</td>
          <xsl:for-each
select="//*[starts-with(name(),'chan')][generate-id() =
generate-id(key('by-chan',.)[1])]">
            <td>Channels=<xsl:value-of select="." /></td>
          </xsl:for-each>
      </th>
      <xsl:variable name="rtf1">
        <xsl:for-each
select="//*[starts-with(name(),'chan')][generate-id() =
generate-id(key('by-chan',.)[1])]">
          <x><xsl:value-of select="." /></x>
        </xsl:for-each>
      </xsl:variable>
      <xsl:apply-templates select="devices">
        <xsl:with-param name="rtf1" select="$rtf1" />
      </xsl:apply-templates>
    </table>
    </body>
  </html>
</xsl:template>

<xsl:template match="devices">
  <xsl:param name="rtf1" />

  <xsl:for-each select="device">
    <xsl:variable name="rtf2">
      <xsl:copy-of select="." />
    </xsl:variable>
    <tr>
      <td><xsl:value-of select="deviceID" /></td>
      <td><xsl:value-of select="desc" /></td>
      <xsl:for-each select="common:node-set($rtf1)/x[not(. =
common:node-set($rtf2)/*/*)]">
        <td><xsl:value-of select="." /></td>
      </xsl:for-each>
      <xsl:for-each
select="common:node-set($rtf2)/*/*[starts-with(name(),'chan')][generate-id()
= generate-id(key('by-chan',.)[1])]">
        <td><xsl:value-of select="count(key('by-chan',.))" /></td>
      </xsl:for-each>
    </tr>
  </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

I am producing HTML, which you can change as required.

Regards,
Mukul

On 4/28/06, Andrew Quan <aquan(_at_)netstarnetworks(_dot_)com(_dot_)au> wrote:
Hi,

I'm Using XSLT 1.0

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!

Given a data set similar to this:

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

Is there a way to count how many times, for example, a 2 appears in all
attributes starting with the name "chan"?

Ideal output:

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

Any help appreciated, i'll keep searching till then
Andrew

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