У меня есть следующий шаблон xsl, который я использую для группировки моих файлов xsl. У меня проблема в том, что мне нужно указать @Title в верхнем регистре, поскольку в настоящее время моя группа видит верхний и нижний регистр как отдельные группы.
<xsl:key name = "rows-by-title" match = "Row" use = "substring(@Title,1,1)" />
<xsl:template name = "Meunchian" match = "/dsQueryResponse/Rows">
<xsl:for-each select = "Row[count(. | key('rows-by-title', substring(@Title,1,1))[1]) = 1]">
<xsl:sort select = "substring(@Title,1,1)" />
<p></p><xsl:value-of select = "substring(@Title,1,1)" /><br />
<xsl:for-each select = "key('rows-by-title', substring(@Title,1,1))">
<xsl:value-of select = "@Title" /><br/>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
Я попытался использовать шаблон вызова и установить переменную, но xsl, похоже, не нравится:
<xsl:key name = "rows-by-title" match = "Row" use = "substring(@Title,1,1)" />
<xsl:template name = "Meunchian" match = "/dsQueryResponse/Rows">
<xsl:for-each select = "Row[count(. | key('rows-by-title', substring(@Title,1,1))[1]) = 1]">
<xsl:variable name = "myTitle">
<xsl:call-template name = "to-upper">
<xsl:with-param name = "text">
<xsl:value-of select = "@Title"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<p></p><xsl:value-of select = "$myTitle" /><br />
<xsl:for-each select = "key('rows-by-title', substring(@Title,1,1))">
<xsl:value-of select = "@Title" /><br/>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
То, что я пытаюсь достичь, - это группировка meunchian, но без учета регистра - надеюсь, это имеет смысл!
Киран





Способ преобразования строчных букв в верхние - использовать Функция XPath translate ().
С его помощью можно выразить желаемое преобразование следующим образом:
<xsl:stylesheet version = "1.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:output method = "xml"/>
<xsl:variable name = "vLower" select=
"'abcdefghijklmnopqrstuvwxyz'"
/>
<xsl:variable name = "vUpper" select=
"'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"
/>
<xsl:key name = "rows-by-title" match = "Row" use=
"translate(substring(@Title,1,1),
'abcdefghijklmnopqrstuvwxyz',
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
)" />
<xsl:template match = "/">
<html>
<xsl:apply-templates select = "*/*"/>
</html>
</xsl:template>
<xsl:template name = "Meunchian" match = "/dsQueryResponse/Rows">
<xsl:for-each select=
"Row[generate-id()
=
generate-id(key('rows-by-title',
translate(substring(@Title,1,1),
$vLower,
$vUpper)
)[1]
)
]">
<xsl:sort select = "translate(substring(@Title,1,1),
$vLower,
$vUpper)" />
<p></p>
<xsl:value-of select = "translate(substring(@Title,1,1),
$vLower,
$vUpper)" />
<br />
<xsl:for-each select=
"key('rows-by-title',
translate(substring(@Title,1,1),
$vLower,
$vUpper)">
<xsl:value-of select = "@Title" />
<br/>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
При применении к следующему XML-документу:
<dsQueryResponse>
<Rows>
<Row Title = "Agenda" />
<Row Title = "Policy" />
<Row Title = "policy" />
<Row Title = "Report" />
<Row Title = "report" />
<Row Title = "Test2" />
<Row Title = "test1" />
<Row Title = "Boo" />
<Row Title = "foo" />
</Rows>
</dsQueryResponse>
дает желаемый результат:
<html>
<p/>A
<br/>Agenda
<br/>
<p/>B
<br/>Boo
<br/>
<p/>F
<br/>foo
<br/>
<p/>P
<br/>Policy
<br/>policy
<br/>
<p/>R
<br/>Report
<br/>report
<br/>
<p/>T
<br/>Test2
<br/>test1
<br/>
</html>
В XPath 2.0 будет использоваться функция upper-case () для преобразования нижнего регистра в верхний регистр.
Также группировку в XSLT 2.0 можно лучше выразить с помощью <xsl:for-each-group>
инструкция.