Re: [xsl] comparison of attribute values

Subject: Re: [xsl] comparison of attribute values
From: Joerg Heinicke <joerg.heinicke@xxxxxx>
Date: Fri, 31 May 2002 01:13:54 +0200
Hello J.Pietschmann,

your stylesheet looks a bit more than buggy ;-)
key('fee-currency') is not possible and the Muenchian Method for grouping is missing.


Hello John,

here is my stylesheet:

<xsl:key name="fee-currency" match="fee" use="@currency"/>

<xsl:template match="fees">
<xsl:variable name="unique-currencies" select="*/fee[count( . | key('fee-currency', @currency)[1]) = 1]"/>
<table border="1">
<tr>
<td>fee</td>
<xsl:for-each select="$unique-currencies">
<td><xsl:value-of select="@currency"/></td>
</xsl:for-each>
</tr>
<xsl:for-each select="*/fee">
<tr>
<td><xsl:value-of select="@name"/></td>
<xsl:variable name="this-fee" select="."/>
<xsl:for-each select="$unique-currencies">
<td>
<xsl:value-of select="$this-fee[@currency = current()/@currency]/amount"/>
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
<tr>
<td>total</td>
<xsl:for-each select="$unique-currencies">
<td><xsl:value-of select="/fees/total[@currency = current()/@currency]"/></td>
</xsl:for-each>
</tr>
</table>
</xsl:template>


Note: I used the suggestion with <fee name="fee1"/>. So the XML looks like:

<fees>
  <basic-fees>
    <fee name="fee1" currency="USD"><amount>20</amount></fee>
    <fee name="fee2" currency="EUR"><amount>25</amount></fee>
  </basic-fees>
  <special-fees>
    <fee name="fee3" currency="EUR"><amount>20</amount></fee>
  </special-fees>
  <total currency="USD">65</total>
</fees>

Result:

<table border="1">
  <tr>
    <td>fee</td>
    <td>USD</td>
    <td>EUR</td>
  </tr>
  <tr>
    <td>fee1</td>
    <td>20</td>
    <td></td>
  </tr>
  <tr>
    <td>fee2</td>
    <td></td>
    <td>25</td>
  </tr>
  <tr>
    <td>fee3</td>
    <td></td>
    <td>20</td>
  </tr>
  <tr>
    <td>total</td>
    <td>65</td>
    <td></td>
  </tr>
</table>

For more information on Muenchian Method have a look at http://www.jenitennison.com/xslt/grouping/muenchian.xml.

Regards,

Joerg


J.Pietschmann wrote:
jdunning wrote:

Hi,
What I would like to do is to insert a row into a table if there is a
difference in an attribute value anywhere in the document; for example, this
data should produce 2 columns (USD and EUR):


<fees>
    <basic-fees>
        <fee1 currency="USD"><amount>20</amount></fee1>
        <fee2 currency="EUR"><amount>25</amount></fee2>
    </basic-fees>
    <special-fees>
        <fee3 currency="EUR"><amount>20</amount></fee3>
    </special-fees>
    <total currency="USD">65</total>
</fees>

<!-- desired output for above doc -->
<table>
    <tr><td>FEE</td><td>USD</td><td>EUR</td></tr>
    <tr><td>fee1</td><td> 20   </td><td>        </td></tr>
    <tr><td>fee2 </td><td>        </td><td> 25  </td></tr>
    <tr><td>fee3</td><td>        </td><td>  20  </td> </tr>
    <tr><td>total</td><td> 65   </td><td>       </td></tr>
</table>


It's a grouping problem.

<xsl:key name="fee-currency" match="*[@currency and substring(local-name(),1,3)='fee']"
use="@currency"/>


  <xsl:template match="fees">
    <table>
     <tr>
      <xsl:for-each select="key('fee-currency')/@currency">
         <td><xsl:value-of select="."/></td>
      </xsl:for-each>
     </tr>
     <xsl:for-each select="*/*[substring(local-name(),1,3)='fee']">
       <tr>
         <xsl:variable name="fee" select="."/>
         <xsl:for-each select="key('fee-currency')/@currency">
           <td>
             <xsl:if test="$fee/@currency=.">
               <xsl:value-of select="$fee/amount"/>
             </xsl:if>
           </td>
         </xsl:for-each>
       </tr>
     </xsl:for-each>
    </xsl:template>

(Beware: untested)


Are you sure your fees are nemed fee1, fee2 rather than <fee name="fee1"> etc?


J.Pietschmann


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list


Current Thread