[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Counting common value within specific attributes

Subject: Re: Counting common value within specific attributes
From: "Mukul Gandhi" <gandhi.mukul@xxxxxxxxx>
Date: Fri, 28 Apr 2006 10:51:35 +0530
common node set
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@xxxxxxxxxxxxxxxxxxxxxx> 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

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.