XSLT:比较用作分组键的字母

时间:2012-05-16 14:09:27

标签: xslt xpath collation xslt-2.0

我想用第一个字母对元素进行分组,但是一些不同的字母应该被认为是相同的:A和Ä(和a和ä)都应该是相同的。

来源:

<root>
  <entry name="Aa" />
  <entry name="Ab" />
  <entry name="Äa" />
  <entry name="Ac" />
  <entry name="Ba" />
</root>

转型:

<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
  <xsl:output indent="yes"/>

  <xsl:template match="root">
    <root>
      <xsl:for-each-group select="entry" group-by="upper-case(substring(@name,1,1))">
        <key><xsl:value-of select="current-grouping-key()"/></key>
      </xsl:for-each-group>
    </root>
  </xsl:template>

</xsl:stylesheet>

结果现在:

<root>
   <key>A</key>
   <key>Ä</key>
   <key>B</key>
</root>

我想要的结果是:

<root>
   <key>A</key>
   <key>B</key>
</root>

除“Bb”以外的所有条目都应在第一组中。

我认为成功的关键是使group-by()函数正确处理a,A,ä和Ä相等(对于某些德国排序/排序规则,这是正确的)。但我还没有找到可以处理它的xpath函数。

2 个答案:

答案 0 :(得分:2)

有两种可能的方法:

(a)使用xsl:for-each-group的collat​​ion属性,指定具有正确比较语义的排序规则。不幸的是,这将取决于您的XSLT处理器。例如,对于Saxon,您可以使用

http://saxon.sf.net/collation?lang=de;ignore-case=yes;ignore-modifiers=yes

如下所述:

http://www.saxonica.com/documentation/extensibility/collation.xml

(b)另一种选择是“自己动手”,因为这里的大多数答案都是建议的:也就是说,写一些函数来规范化大小写并在进行分组之前去除重音。调用小写()或大写()并不适用于规范化大小写,尽管大写()对德语来说可能是好的,主要问题是将“ß”和“ss”组合在一起。删除重音可以通过使用normalize-unicode()来规范化为Unicode分解的普通形式,然后使用replace()来消除类别\ p {Lm}中的字符。

我建议使用归类。

答案 1 :(得分:1)

translate(substring(@name,1,1), 'Ä', 'A')怎么样?