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 函数。

4

2 回答 2

2

有两种可能的方法:

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

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

如此处所述:

http://www.saxonica.com/documentation/extensibility/collat​​ion.xml

(b)另一种方法是“自己做”,因为这里的大多数答案一直在推荐:也就是说,在进行分组之前编写一些函数来规范化大小写并去除重音符号。调用 lower-case() 或 upper-case() 对于规范化大小写并不完美,尽管对于主要问题是将 "ß" 和 "ss" 组合在一起的德语来说,upper-case() 可能是可以的。摆脱重音可以通过使用 normalize-unicode() 标准化为 Unicode 分解的范式,然后 replace() 来消除类别 \p{Lm} 中的字符。

我建议使用排序规则。

于 2012-05-16T16:26:58.193 回答
1

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

于 2012-05-16T14:11:56.223 回答