如何在XSLT中分组元素

4

在使用XSLT分组元素时遇到了困难。 我是否需要使用xsl:key?如果是这样,如何使用? 或者更多的xsl:for-each? 这是我的问题。我的XML文件:

<page>
<name>test</name>
<property id="416" name="country" type="relation">
    <title>Country</title>
        <value>
            <item id="1014" name="Canada"/>
        </value>
    </property>
</page>

有一组20个物品,每个物品都有一个名称(不重复),并且来自于一个国家,可能会有多个物品来自同一个国家。 如何将这些物品按照国家进行分组? 例如:

<h1>Canada</h1>
<h2>test<h2>
<h2>test2<h2>

<h1>England</h1>
<h2>test3</h2>
<h2>test3</h2>

更新:

   <page id="423" parentId="421" link="/producers/oao_nii_elpa/" is-active="1" object-id="1020" type-id="67" type-guid="catalog-category" update-time="1350295423" alt-name="oao_nii_elpa">
<basetype id="44" module="catalog" method="category">Catalog category</basetype>
<name>Nii elpa</name>
<properties>
<group id="130" name="common">
<title>Params</title>
<property id="116" name="h1" type="string">
<title>H1 field</title>
<value>Nii elpa</value>
</property>
</group>
<group id="131" name="menu_view">
<title>Menu View</title>
<property id="123" name="header_pic" type="img_file">
<title>Header_Pic</title>
<value path="./images/cms/headers/elpa.jpg" folder="/images/cms/headers" name="elpa" ext="jpg" width="139" height="63">/images/cms/headers/elpa.jpg</value>
</property>
</group>
<group id="133" name="additional">
<title>Additional</title>
<property id="416" name="country" type="relation">
<title>Country</title>
<value>
<item id="3" guid="a1e3ae17e80ba2b4a3ddb1b855430346f74b8d48" name="England" type-id="4" type-guid="d69b923df6140a16aefc89546a384e0493641fbe" ownerId="42" xlink:href="uobject://3"/>
</value>
</property>
</group>
</properties>
</page>

XSLT 1.0还是2.0?使用2.0版本可以更轻松地进行分组。 - Michael Kay
那不是你的 XML 文件 - "England" 在里面根本没有被引用。请展示真正的 XML 输入。 - ABach
你有尝试过吗?请展示一下你目前的努力。 - Tomalak
你的XSLT文件在哪里? - duffy356
1个回答

2
对于XSLT 1.0,分组的方式是通过Muenchian方法实现的,例如:
(来源:http://www.jenitennison.com/xslt/grouping/muenchian.html

我们有一个XML:

<records>
    <contact id="0001">
        <title>Mr</title>
        <forename>John</forename>
        <surname>Smith</surname>
    </contact>
    <contact id="0002">
        <title>Dr</title>
        <forename>Amy</forename>
        <surname>Jones</surname>
    </contact>
    ...
</records>

我们希望按姓氏分组,并生成以下输出:
Jones,<br />
    Amy (Dr)<br />
    Brian (Mr)<br />
Smith,<br />
    Fiona (Ms)<br />
    John (Mr)<br />

以下是使用XSLT 1.0模板和关键字实现的:

<xsl:key name="contacts-by-surname" match="contact" use="surname" />
<xsl:template match="records">
    <xsl:for-each select="contact[count(. | key('contacts-by-surname', surname)[1]) = 1]">
        <xsl:sort select="surname" />
        <xsl:value-of select="surname" />,<br />
        <xsl:for-each select="key('contacts-by-surname', surname)">
            <xsl:sort select="forename" />
            <xsl:value-of select="forename" /> (<xsl:value-of select="title" />)<br />
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

您的问题模板应该类似于以下内容(未经测试):
<xsl:key name="page-by-country" match="page" use="property[@name='country']/value/item/@name" />
<xsl:template match="pages">
    <xsl:for-each select="page[count(. | key('page-by-country', property[@name='country']/value/item/@name)[1]) = 1]">
        <xsl:sort select="property[@name='country']/value/item/@name" />
        <h1><xsl:value-of select="property[@name='country']/value/item/@name" /></h1>
        <xsl:for-each select="key('page-by-country', property[@name='country']/value/item/@name)">
            <xsl:sort select="name" />
            <h2><xsl:value-of select="name"/></h2>
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

请查看以下解决方案示例,涉及您的问题:xsltransform.net

我更新了答案,现在它是可行的。原始答案有一些错别字。请查看链接以获取一个可行的示例。 - Joep

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接