I have an approximately this kind of xml:
<charge>
<price></price>
<amount></amount>
<name>
<KeyValuePair>
<Key>
en-us
</Key>
<Value>
Name in english
</Value>
</KeyValuePair>
<KeyValuePair>
<Key>
ru-ru
</Key>
<Value>
Name in russian
</Value>
</KeyValuePair>
</name>
</charge>
How can I group the charges by name field having fixed language? For instance group charges by english version of name using xlt 1.0? I suppose there wouldn't be an issues with xslt 2.0 where for-each-group is present. But in 1.0 I couldn't even create an xsl:key with complex instructions.
<charge>
<price>2</price>
<amount>3</amount>
<name>
<KeyValuePair>
<key>en-us</key>
<value>mobile</value>
</KeyValuePair>
</name>
</charge>
<charge>
<price>4</price>
<amount>3</amount>
<name>
<KeyValuePair>
<key>en-us</key>
<value>mobile</value>
</KeyValuePair>
</name>
</charge>
<charge>
<price>6</price>
<amount>3</amount>
<name>
<KeyValuePair>
<key>en-us</key>
<value>computer</value>
</KeyValuePair>
</name>
</charge>
<charge>
<price>8</price>
<amount>3</amount>
<name>
<KeyValuePair>
<key>en-us</key>
<value>computer</value>
</KeyValuePair>
</name>
</charge>
en-us
Very approximately: I want my xslt rendering to transform it like this:
mobile 6
computer 14
It groups Charges by name and summurizes prices. An we have a complex rules for getting the translation: 1. We define a default language - if we have no this language specified in XML, we take a default language for xslt(manually set by developer). 2. If the node have no translation for default language, we check for translation on FallbackLanguage(always en-us). 3. If we didn't specify the translation before, we set a translated value to [NO NAME]
My idea was to incapsulate translation logic into the separate template:
<xsl:variable name="ChargesForDisplay">
<xsl:for-each select="/i:Invoice/i:Charges/i:Charge[not(@*[1]='TaxCharge')]">
<chargeset>
<chargeName>
<xsl:call-template name="GetLocalizedEntity">
<xsl:with-param name="ContainerPath" select="./i:Product/i:Name"></xsl:with-param>
</xsl:call-template>
</chargeName>
<charge>
<xsl:value-of select="current()"/>
</charge>
</chargeset>
</xsl:for-each>
</xsl:variable>
So after that I wanted to have variable ChargesToDisplay consist of many pairs look like
<name>SomeName</name>
<Charge>.... Charge content ....<Charge>
and do all grouping on ChargesToDisplay. GetLocalizedEntity implementation:
<xsl:template name ="GetLocalizedEntity">
<xsl:param name="ContainerPath"></xsl:param>
<xsl:choose>
<xsl:when test="$ContainerPath/a:KeyValueOfstringstring[a:Key=$TemplateLanguage]/a:Value != ''">
<xsl:value-of select="$ContainerPath/a:KeyValueOfstringstring[a:Key=$TemplateLanguage]/a:Value"/>
</xsl:when>
<xsl:when test="$ContainerPath/a:KeyValueOfstringstring[a:Key=$FallBackLanguage]/a:Value != ''">
<xsl:value-of select="$ContainerPath/a:KeyValueOfstringstring[a:Key=$FallBackLanguage]/a:Value"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>[NO NAME]</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>