2

特定の属性に基づいて値をグループ化する必要があります。したがって、for-each-group を使用したいと思います。

これは私が使用している入力 XML です。

<?xml version="1.0" encoding="ISO-8859-1"?>
<cities>
  <city country="Germany"   continent="Europe">Munich</city>
  <city country="Germany"   continent="Europe">Dortmund</city>
  <city country="France"    continent="Europe">Brest</city>
  <city country="Japan"         continent="Asia" >Tokyo</city>
  <city country="Korea"      continent="Asia" >Seoul</city>
  <city country="Germany"   continent="Europe">Hannover</city>
  <city country="Poland"         continent="Europe">Krakau</city>
  <city country="Russia"      continent="Asia" >Omsk</city>
  <city country="Japan"         continent="Asia" >Kobe</city>
  <city country="Japan"         continent="Asia" >Ibaraki</city>
  <city country="Russia"      continent="Europe">St. Petersburg</city>
  <city country="Saudi-Arabia" continent="Africa">Riad</city>
  <city country="Ireland"        continent="Europe">Galway</city>
  <city country="Cameroon"       continent="Africa">Yaoundé</city>
  <city country="Austria"    continent="Europe">Vienna</city>
</cities>

ここで、ネストされたリストの形式の出力ファイルを作成したいと思います。
まず、大陸ごとにグループ化し、次に国ごとにグループ化します。つまり、国と大陸内の都市をグループ化します。

出力は次のようになります。

<ul>
  <li>Europe
    <ul>
      <li>Germany
        <ul>
          <li>Munich</li>
          <li>Dortmund</li>
          <li>...</li>
        </ul>          
      </li>
      <li>France
        <ul>
          <li>...</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>Asia
    <ul>...</ul>
  </li>
  <li>Africa
    <ul>...</ul>
  </li>
</ul>

これまでのところ、次の XSLT スタイルシートがあります。

<xsl:template match="cities">
  <ul>
    <xsl:for-each-group select="city" group-by="@continent">
      <li>
        <xsl:value-of select="@continent" />
          <xsl:for-each-group select="stadt" group-by="@land">
           <ul>
             <li>
               <xsl:value-of select="@land" />
             </li>
           </ul>
         </xsl:for-each-group>
      </li>
    </xsl:for-each-group>
  </ul>
</xsl:template>

これは、最初のレベル、つまり大陸ごとのグループ化ではうまく機能します。ただし、リスト内のネストされたレベルでは機能しません。現在の大陸だけを国別にグループ化するには、現在の grouping-element を参照する方法が必要です。

これを行うための最良/最も便利な方法は何ですか?

4

1 に答える 1

4

ネストされたxsl:for-each-groupが、XML に表示されない要素 stadt と属性 @land を参照しているためXSLTは XML と完全には一致していないようです。ただし、実際に使用する必要があると思うのは、グループ内の要素を反復処理するためのcurrent-group()関数です。この場合、現在の大陸内の国ごとにグループ化しています。

<xsl:for-each-group select="current-group()" group-by="@country">

そして、国内の都市を反復処理するために、別のネストされたループが必要になります。

<xsl:for-each select="current-group()">

ここに完全な XSLT があります

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>
   <xsl:template match="cities">
      <ul>
         <xsl:for-each-group select="city" group-by="@continent">
            <li>
               <xsl:value-of select="@continent"/>
               <ul>
                  <xsl:for-each-group select="current-group()" group-by="@country">
                     <li>
                        <xsl:value-of select="@country"/>
                        <ul>
                           <xsl:for-each select="current-group()">
                              <li>
                                 <xsl:value-of select="."/>
                              </li>
                           </xsl:for-each>
                        </ul>
                     </li>
                  </xsl:for-each-group>
               </ul>
            </li>
         </xsl:for-each-group>
      </ul>
   </xsl:template>
</xsl:stylesheet>

指定された XML で実行すると、以下が出力されます。

<ul>
   <li>Europe
      <ul>
         <li>Germany
            <ul>
               <li>Munich</li>
               <li>Dortmund</li>
               <li>Hannover</li>
            </ul></li>
         <li>France
            <ul>
               <li>Brest</li>
            </ul></li>
         <li>Poland
            <ul>
               <li>Krakau</li>
            </ul></li>
         <li>Russia
            <ul>
               <li>St. Petersburg</li>
            </ul></li>
         <li>Ireland
            <ul>
               <li>Galway</li>
            </ul></li>
         <li>Austria
            <ul>
               <li>Vienna</li>
            </ul></li>
      </ul></li>
   <li>Asia
      <ul>
         <li>Japan
            <ul>
               <li>Tokyo</li>
               <li>Kobe</li>
               <li>Ibaraki</li>
            </ul></li>
         <li>Korea
            <ul>
               <li>Seoul</li>
            </ul></li>
         <li>Russia
            <ul>
               <li>Omsk</li>
            </ul></li>
      </ul></li>
   <li>Africa
      <ul>
         <li>Saudi-Arabia
            <ul>
               <li>Riad</li>
            </ul></li>
         <li>Cameroon
            <ul>
               <li>Yaound</li>
            </ul></li>
      </ul></li>
</ul>

過度のインデントを避けるために、最も内側のxsl:for-eachxsl:apply-templatesに置き換えることをお勧めします。

于 2012-11-01T16:27:55.447 に答える