1

次のようなXMLファイルがあり、出版年に基づいて本をグループ化し、各年の本の数を数えたいと思います。結果を昇順で並べ替えます。

<body>
  <outline text="A">
    <outline text="Abelson, Harold" author="Harold Abelson" title="Struktur und Interpretation von Computerprogrammen. Eine Informatik-Einführung" publisher="Springer Verlag" isbn="3540520430" year="1991"/>
    <outline text="Abrahams, Paul W." author="Paul W. Abrahams" title="Tex for the Impatient" publisher="Addison-Wesley Pub Co" isbn="0201513757" year="2000"/>
  </outline>
  <outline text="B">
    <outline text="Bach, Fred" author="Fred Bach" title="UNIX Handbuch zur Programmentwicklung" publisher="Hanser Fachbuchverlag" isbn="3446151036"/>
    <outline text="Bach, Maurice J." author="Maurice J. Bach" title="Design of the UNIX Operating System" publisher="Prentice Hall PTR" isbn="0132017997" year="1986"/>
  </outline>
</body>

これが例外的な出力です

    <p> Group by Year </p>
    <table border="1">
        <tr bgcolor="yellow">
            <th>Year</th>
            <th>Number</th>
        </tr>
        <tr>
            <td>1963</td>
            <td>1</td>
        </tr>
        <tr>
            <td>1966</td>
            <td>1</td>
        </tr>

これが私のコードです:

<xsl:template match="body">
    <xsl:copy>
      <table border="1">     
        <tr bgcolor="Yellow">
            <th class="cell"><span> Year </span></th>
            <th class="cell"><span> Count </span></th>
        </tr>
        <xsl:apply-templates select="outline"/>
      </table>
    </xsl:copy>
  </xsl:template>

 <xsl:key  name="groupbyyear"  match="outline" use="@year"/)/>
   <xsl:template match="outline/outline">
    <tr>
      <xsl:sort select="year" order="ascending" />
    </tr>
  </xsl:template>


</xsl:stylesheet>

xslキー関数の使用方法がわかりません。また、キー関数の後にテンプレート内で何をすべきですか?

4

1 に答える 1

1

このXSLT1.0変換

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:key name="kOutlineByYear" match="outline/outline" use="@year"/>

 <xsl:template match="/*">
    <p> Group by Year </p>
    <table border="1">
        <tr bgcolor="yellow">
            <th>Year</th>
            <th>Number</th>
        </tr>
     <xsl:apply-templates select=
      "outline/outline[generate-id()
                      =generate-id(key('kOutlineByYear',@year)[1])
                      ]">
      <xsl:sort select="@year" data-type="number"/>
     </xsl:apply-templates>
    </table>
 </xsl:template>

 <xsl:template match="outline/outline">
   <tr>
     <td><xsl:value-of select="@year"/></td>
     <td><xsl:value-of select="count(key('kOutlineByYear',@year))"/></td>
   </tr>
 </xsl:template>
</xsl:stylesheet>

次のXMLドキュメントに適用した場合(より代表的なものにするために小さな修正が加えられたもの):

<body>
  <outline text="A">
    <outline text="Abelson, Harold"
     author="Harold Abelson"
     title="Struktur und Interpretation von Computerprogrammen. Eine Informatik-Einführung"
     publisher="Springer Verlag"
     isbn="3540520430" year="1991"/>
    <outline text="Abrahams, Paul W." author="Paul W. Abrahams"
     title="Tex for the Impatient"
     publisher="Addison-Wesley Pub Co" isbn="0201513757" year="2000"/>
  </outline>
  <outline text="B">
    <outline text="Bach, Fred" author="Fred Bach"
    title="UNIX Handbuch zur Programmentwicklung"
    publisher="Hanser Fachbuchverlag" isbn="3446151036" year="2000"/>
    <outline text="Bach, Maurice J."
    author="Maurice J. Bach"
    title="Design of the UNIX Operating System"
    publisher="Prentice Hall PTR" isbn="0132017997" year="1986"/>
  </outline>
</body>

必要な正しい結果を生成します。

<p> Group by Year </p>
<table border="1">
   <tr bgcolor="yellow">
      <th>Year</th>
      <th>Number</th>
   </tr>
   <tr>
      <td>1986</td>
      <td>1</td>
   </tr>
   <tr>
      <td>1991</td>
      <td>1</td>
   </tr>
   <tr>
      <td>2000</td>
      <td>2</td>
   </tr>
</table>

説明

Muenchianグループ化方法の適切な使用。


II。XSLT 2.0ソリューション

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:key name="kOutlineByYear" match="outline/outline" use="@year"/>

 <xsl:template match="/*">
    <p> Group by Year </p>
    <table border="1">
        <tr bgcolor="yellow">
            <th>Year</th>
            <th>Number</th>
        </tr>
     <xsl:for-each-group select="outline/outline"
      group-by="@year">
       <xsl:sort select="current-grouping-key()" data-type="number"/>
           <tr>
             <td><xsl:value-of select="current-grouping-key()"/></td>
             <td><xsl:value-of select="count(current-group())"/></td>
           </tr>
      </xsl:for-each-group>
    </table>
 </xsl:template>
</xsl:stylesheet>

この変換が同じXMLドキュメント(上記)に適用されると、同じ正しい結果が生成されます。

<p> Group by Year </p>
<table border="1">
   <tr bgcolor="yellow">
      <th>Year</th>
      <th>Number</th>
   </tr>
   <tr>
      <td>1986</td>
      <td>1</td>
   </tr>
   <tr>
      <td>1991</td>
      <td>1</td>
   </tr>
   <tr>
      <td>2000</td>
      <td>2</td>
   </tr>
</table>

説明

  1. 属性を指定<xsl:for-each-group>したXSLT2.0命令の使用。group-by

  2. XSLT2.0関数の使用current-group()current-grouping-key()

于 2013-01-24T04:35:54.750 に答える