我有一种近似这种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>
如何按照固定语言的名称字段对费用进行分组?例如,使用xlt 1.0的英文版名称的小组收费?我想xslt 2.0不存在问题,其中for-each-groups存在。但是在1.0中我甚至无法使用复杂的指令创建一个xsl:key。
<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
非常近似:我希望我的xslt渲染能够像这样转换它:
mobile 6
computer 14
按名称对费用进行分组并汇总价格。 我们有一个复杂的规则来获得翻译: 1.我们定义一个默认语言 - 如果我们没有在XML中指定这种语言,我们采用xslt的默认语言(由开发人员手动设置)。 2.如果节点没有默认语言的翻译,我们检查FallbackLanguage上的翻译(总是en-us)。 3.如果我们之前没有指定翻译,我们将翻译的值设置为[NO NAME]
我的想法是将翻译逻辑封装到单独的模板中:
<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>
所以在那之后我想要变量ChargesToDisplay由许多对组成,看起来像
<name>SomeName</name>
<Charge>.... Charge content ....<Charge>
并对ChargesToDisplay进行所有分组。 GetLocalizedEntity实现:
<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>
答案 0 :(得分:1)
我相信这应该有效。请试一试。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="text" />
<xsl:param name="templateLanguage" select="'ru-ru'" />
<xsl:param name="fallbackLanguage" select="'en-us'" />
<xsl:key name="itemName" match="chargeSet" use="chargeName"/>
<xsl:template match="/">
<!-- Retrieve chargesForDisplay -->
<xsl:variable name="chargesForDisplay">
<xsl:apply-templates select="//charge" mode="buildForDisplay" />
</xsl:variable>
<root>
<xsl:apply-templates select="msxsl:node-set($chargesForDisplay)/*" />
</root>
</xsl:template>
<xsl:template match="text()" />
<xsl:template
match="chargeSet[generate-id(.)=generate-id(key('itemName',chargeName)[1])]">
<xsl:variable name="matchingItems" select="key('itemName', chargeName)" />
<xsl:value-of
select="concat(chargeName, ' ', sum($matchingItems/charge/price), '
')"/>
</xsl:template>
<xsl:template match="charge" mode="buildForDisplay">
<chargeSet>
<chargeName>
<xsl:call-template name="GetLocalizedEntry">
<!-- Pass in all KeyValuePairs with present, non-blank values-->
<xsl:with-param name="keyValuePairs"
select="name/KeyValuePair[normalize-space(value)]" />
</xsl:call-template>
</chargeName>
<xsl:copy-of select="." />
</chargeSet>
</xsl:template>
<xsl:template name="GetLocalizedEntry">
<xsl:param name="keyValuePairs" />
<xsl:variable name="templateLanguageMatch"
select="$keyValuePairs[key = $templateLanguage]/value" />
<xsl:variable name="fallbackLanguageMatch"
select="$keyValuePairs[key = $fallbackLanguage]/value" />
<xsl:choose>
<xsl:when test="$templateLanguageMatch">
<xsl:value-of select="$templateLanguageMatch"/>
</xsl:when>
<xsl:when test="$fallbackLanguageMatch">
<xsl:value-of select="$fallbackLanguageMatch"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>[NO NAME]</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
在此输入XML上运行时(根节点和一些额外的<charges>
添加到您的示例中):
<charges>
<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>
<charge>
<price>8</price>
<amount>3</amount>
<name>
<KeyValuePair>
<key>ja-jp</key>
<value>計算機</value>
</KeyValuePair>
</name>
</charge>
<charge>
<price>13</price>
<amount>3</amount>
<name>
<KeyValuePair>
<key>ru-ru</key>
<value>shelf</value>
</KeyValuePair>
</name>
</charge>
</charges>
生成此输出:
mobile 6
computer 14
[NO NAME] 8
shelf 13