我必须根据某些属性对值进行分组。因此,我想使用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>
这适用于第一级,即按大洲分组。 但它不适用于列表中的嵌套级别。 我需要一种方法来引用当前的分组元素,以便按国家分组,只针对当前大陆。
最好/最方便的方法是什么?
答案 0 :(得分: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:apply-templates 替换最内部的 xsl:for-each ,以避免过度缩进!