How to group items in XSLT

Faced with difficulty solving a task by grouping XSLT elements. Should I use the xsl key :? if so, how to do it or more xsl: for each? Here is my problem. My xml file:

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

and items, such as 20, each of which has a name (repeating, and its country, can be repeated) How to get such elements grouped by country? eg:

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

UPDATE:

  <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> 
+4
source share
1 answer

For XSLT 1.0, the grouping method is performed using the muenchian method, for example:
(source: http://www.jenitennison.com/xslt/grouping/muenchian.html )

We have 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> 

And we will not group by last name and print the following result:

 Jones,<br /> Amy (Dr)<br /> Brian (Mr)<br /> Smith,<br /> Fiona (Ms)<br /> John (Mr)<br /> 

This is done using the following template and XSLT 1.0 key:

 <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> 

The template for your problem will look like this (untested):

 <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> 

See this working example for your problem: xsltransform.net

+2
source

All Articles