Altova Mailing List Archives>Archive Index >microsoft.public.xsl Archive Home >Recent entries >Thread Prev - Newbie at xslt - any help? [Thread Next] Re: Newbie at xslt - any help?To: NULL Date: 8/13/2007 9:23:00 PM
Illustris wrote:
> Hello all-
>
> I don't even know where to start w/this one. I'm pretty weak at xslt...
>
> My XML:
> <Markets>
> <Market name="US">
> <Language name="English" />
> </Market>
> <Market name="Australia">
> <Language name="English" />
> </Market>
> <Market name="Canada">
> <Language name="English" />
> <Language name="French" />
> </Market>
> <Market name="UK">
> <Language name="English" />
> </Market>
> <Market name="Hong-Kong">
> <Language name="English" />
> <Language name="Chinese/T" />
> </Market>
> <Market name="India">
> <Language name="English" />
> </Market>
> </Markets>
>
> I need the above to transform to:
>
> <Languages>
> <Language name="English">
> <Market name="US" />
> <Market name="Australia" />
> <Market name="Canada" />
> <Market name="UK" />
> <Market name="Hong-Kong" />
> <Market name="India" />
> </Language>
> <Language name="French">
> <Market name="Canada" />
> </Language>
> <Language name="Chinese/T">
> <Market name="Hong-Kong" />
> </Language>
> </Languages>
>
> As you can see, I need to group the market name attribute based on the
> Language's name attribute. Can anyone assist please?
Try this (Muenchian grouping):
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="lang" match="Language" use="@name"/>
<xsl:template match="/">
<Languages>
<xsl:for-each select="//Language">
<xsl:if test="count(.|key('lang',@name)[1])=1">
<Language name="{@name}">
<xsl:for-each select="//Language[@name=current()/@name]">
<Market name="{parent::Market/@name}"/>
</xsl:for-each>
</Language>
</xsl:if>
</xsl:for-each>
</Languages>
</xsl:template>
</xsl:stylesheet>
The key "lang" indexes all Language elements by their name attribute.
The key() function retrieves those matching the current language name,
but only the first in each case (the [1]). The count() function counts
the union of the current Language element and the indexed one, and the
condition tests if these two elements are one and the same (ie if this
is the first occurrence of the matching name). That lets it cycle
through the first of each Language. Within that, it accesses each
matching Language element and outputs its parent Market name.
In XSLT2 it's more elegant, but not as widely implemented as yet.
///Peter
--
XML FAQ: http://xml.silmaril.ie/
| ||||||
| Company | Legal | Press | Partners | Careers | Sitemap | Contact Us | Altova Blog | Mobile | Full Site | |||
|
