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>

这适用于第一级,即按大陆分组。但它不适用于列表中的嵌套级别。我需要一种方法来引用当前的分组元素,以便仅针对当前大陆按国家/地区分组。

最好/最方便的方法是什么?

4

1 回答 1

4

您的 XSLT 似乎与 XML 不太匹配,因为您嵌套的xsl:for-each-group引用了一个元素stadt和一个属性@land,它们没有出现在 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-each替换为xsl:apply-templates以避免过度缩进!

于 2012-11-01T16:27:55.447 回答