Frage

<CATALOG>
  <CD>
    <TITLE>Empire Burlesque</TITLE>
    <ARTIST>Bob Dylan</ARTIST>
    <COUNTRY>USA</COUNTRY>
    <COMPANY>Columbia</COMPANY>
    <PRICE>10.90</PRICE>
    <YEAR>1985</YEAR>
  </CD>
  <CD>
    <TITLE>The very best of</TITLE>
    <ARTIST>Cat Stevens</ARTIST>
    <COUNTRY>USA</COUNTRY>
    <COMPANY>Island</COMPANY>
    <PRICE>11.90</PRICE>
    <YEAR>1994</YEAR>
  </CD>  
  <CD>
    <TITLE>Hide your heart</TITLE>
    <ARTIST>Bonnie Tylor</ARTIST>
    <COUNTRY>UK</COUNTRY>
    <COMPANY>CBS</COMPANY>
    <PRICE>9.90</PRICE>
    <YEAR>1988</YEAR>
  </CD>....and so on

I want to write a query in xslt to print the no.of cd's per country. Here's how i approached it.

  • I sorted the cd's based on country in ascending order.
  • then in for-each loop for every country i tried counting the no.of cd's but its printing some weird numbers.

Please help me out in figuring this.

I'm using XSLT 1.0

EDIT: ok so i read about muenchian grouping and tried the following code but im still not getting the desired output. Here's the code

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" />
  <xsl:key name="country" match="//CD" use="COUNTRY" />
  <xsl:template match="/">
   <center>
    <h2>Print the no. of records for each country.</h2>
    </center>
      <xsl:call-template name="query5"/>

  </xsl:template>

  <xsl:template name="query5">

    <table align="center" border="1">
      <tr>
        <th>Country</th>
        <th>Records</th>
      </tr>

      <xsl:for-each select="//CD[generate-id() = generate-id(key('country',COUNTRY)[1])]">
        <xsl:sort select="COUNTRY"/>
        <tr>
          <td>
            <xsl:value-of select="COUNTRY"/>
          </td>
          <td>
            <xsl:for-each select="key('country', COUNTRY)">
              <xsl:value-of select="count(//CD)"/>
            </xsl:for-each>
          </td>
        </tr>
      </xsl:for-each>
    </table>
  </xsl:template>

</xsl:stylesheet>

But im still not getting desired output. Please advice

War es hilfreich?

Lösung

Without testing it myself, here's what I would change:

        <xsl:for-each select="key('country', COUNTRY)">
          <xsl:value-of select="count(//CD)"/>
        </xsl:for-each>

to

        <xsl:value-of select="count(key('country', COUNTRY))" />

Explanation:

  • You have the outer loop doing a proper Muenchian-grouped "for each country"; or more precisely, "for each CD that is the first CD for its respective country". (Good job applying the Muenchian technique BTW, if that's your first time.)
  • Inside that loop, you're asking XPath to count the number of nodes in the set returned by the key for the COUNTRY of the current CD.

Bonus: I like to name keys following Jeni Tennison's example, 'Xs-by-Y', where X is the type of thing returned by the key, and Y is the type of value passed to the key (i.e. what is referenced by the use= attribute). This makes it much easier for me to think straight when defining the key and when using it, so that I don't get confused between what the key() function takes and what it returns. So in your case, naming the key 'CDs-by-COUNTRY' would make the code more readable and help prevent mistakes.

You might choose a different key naming convention, but it helps to have something that makes the identity of the key vs. the value explicit. Especially if you're not doing type checking.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top