【问题标题】:XSL Sort treats lowercase separately from uppercaseXSL 排序将小写与大写分开处理
【发布时间】:2014-03-27 22:28:18
【问题描述】:

我的 XSLT 按字母顺序对姓氏进行排序,但我只是注意到有些名字以“de”和“von”或“van”开头。这些小写前缀被排序并放置在大写名称之后。如何告诉 XSLT 将所有案例排序在一起?

使用 XSLT 1.0

这是对数据进行排序的部分:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="Data">
<xsl:strip-space elements="*"/>
<xsl:template match="Data">
<xsl:copy>
<xsl:apply-templates select="Consultant">
<xsl:sort select="Surname" order="ascending" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>  
<xsl:template match="Consultant">
<consultant><Surname><xsl:value-of select="Surname"/></Surname>
<FirstName><xsl:value-of select="FirstName"/></FirstName>
<!--…-->
</consultant>
</xsl:template>
</xsl:stylesheet>

这是一些示例 XML:

<?xml version="1.0" encoding="UTF-8"?>
<Data>
<consultant>
<Surname>Arnon</Surname>
<FirstName>Lana</FirstName>
</consultant>
<consultant>
<Surname>von Armon</Surname>
<FirstName>George</FirstName>
</consultant>
<consultant>
<Surname>Arnon</Surname>
<FirstName>Lana</FirstName>
</consultant>
<consultant>
<Surname>de Armon</Surname>
<FirstName>George</FirstName>
</consultant>
</Data>

【问题讨论】:

  • 您介意添加一个完整的 XSLT 样式表和一个完整的输入 XML 以便人们可以测试吗?谢谢。
  • 请注明 XSLT 1.0 或 2.0。
  • 好的,添加了更多示例内容,我们正在使用 XSLT 1.0
  • "von Armon" 应该出现在 "Arnon" 之前 - 这是你的意思吗?

标签: xml sorting xslt xslt-1.0


【解决方案1】:

你需要规范化&lt;xsl:sort/&gt;中的大小写

如果您的环境支持 XPATH 2.0,那么您可以使用大写()或小写(),如下所示:

<xsl:sort select="upper-case(Surname)" order="ascending" />

如果您的环境不支持 XPATH 2.0,那么您将需要使用 translate(),如下所示:

<xsl:sort select="translate(Surname, 'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')" order="ascending" />

【讨论】:

  • 不行,我们只能使用 1.0。
  • 我会尝试翻译并告诉你
  • 如果您的环境支持 XSLT 2.0,那么您可以指定用于排序的排序规则并丢弃 translate()“解决方法”(请参阅​​我的答案以获得更好的定义)。
【解决方案2】:

使用 translate() 是一种技巧,只有在您的处理器不支持 &lt;xsl: sort&gt;lang 属性时才应该使用它 - 请参阅 http://www.w3.org/TR/xslt#sorting

【讨论】:

    【解决方案3】:

    排序取决于您在 1.0 和 2.0 中使用的 XSLT 处理器。

    尝试将lang="nl"(或其他合适的语言)添加到 xsl:sort 元素,以获得该语言的语言敏感排序规则。

    【讨论】:

      【解决方案4】:

      大小写函数仅在 XSLT 2.0 中可用,因此您需要手动完成。插入此小写/大写变量并在xsl:sort 中使用translate 进行操作

      <xsl:variable name="smallcase" select="'abcdefghijklmnopqrstuvwxyz'" />
      <xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
      
      <xsl:sort select="translate(Surname, $smallcase, $uppercase)" order="ascending" />
      

      【讨论】:

        【解决方案5】:

        如果我理解正确,问题不在于小写字母与大写字母。您是说“van”、“de”等不计入排序。

        如果是这样,简单地将小写字母翻译成nothing可能会起作用。

        样式表(改编自 @therealmarv 的解决方案)

        <?xml version="1.0" encoding="UTF-8"?>
        <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
            <xsl:output method="xml" indent="yes"/>
            <xsl:strip-space elements="*"/>
        
            <xsl:variable name="smallcase" select="'abcdefghijklmnopqrstuvwxyz'" />
            <xsl:variable name="uppercase" select="''" />
        
            <xsl:template match="Data">
            <xsl:copy>
            <xsl:apply-templates select="consultant">
            <xsl:sort select="translate(Surname, $smallcase, $uppercase)" order="ascending" />
            </xsl:apply-templates>
            </xsl:copy>
            </xsl:template>
        
            <xsl:template match="consultant">
            <consultant><Surname><xsl:value-of select="Surname"/></Surname>
            <FirstName><xsl:value-of select="FirstName"/></FirstName>
            <!--…-->
            </consultant>
            </xsl:template>
        </xsl:stylesheet>
        

        输出

        <?xml version="1.0" encoding="utf-8"?>
        <Data>
           <consultant>
              <Surname>von Armon</Surname>
              <FirstName>George</FirstName>
           </consultant>
           <consultant>
              <Surname>de Armon</Surname>
              <FirstName>George</FirstName>
           </consultant>
           <consultant>
              <Surname>Arnon</Surname>
              <FirstName>Lana</FirstName>
           </consultant>
           <consultant>
              <Surname>Arnon</Surname>
              <FirstName>Lana</FirstName>
           </consultant>
        </Data>
        

        【讨论】:

        • 恕我直言,它们确实很重要,但默认排序顺序是 Unicode。
        • 我的意思是:像“van”或“de”这样的“前缀”不应确定分配给名称的位置。它应该根据后面的名称进行排序(只是猜测 OP 的意图可能是什么)。
        • 不,我们需要按原样尊重名称。但 XML 区分大小写,并将大写和小写视为两个独立的流。第一个解决方案效果很好。 van Helflin 应该被排序为“V”而不是“H”。至少它应该在我们的数据流中。谢谢
        • @MathiasMüller 原则上我倾向于同意你的观点,但实现比仅仅删除小写字符更复杂en masse;例如,“daVinci”应该出现在“DaVinci”旁边,“Smith”需要出现在“Snyde”之前,不一定按文档顺序。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-12-04
        • 2019-01-31
        • 2020-09-13
        • 2012-06-22
        • 1970-01-01
        • 2011-03-18
        • 2016-04-13
        相关资源
        最近更新 更多