【问题标题】:xsl grouping sort problemxsl分组排序问题
【发布时间】:2025-12-14 01:30:01
【问题描述】:

我有以下 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>

我尝试使用 call-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 分组,但不区分大小写 - 希望这有意义!

基兰

【问题讨论】:

    标签: xslt sorting variables grouping


    【解决方案1】:

    小写转大写的方法是使用XPath translate() function

    使用它,表达所需转换的一种方法如下:

    <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 中的分组可以使用&lt;xsl:for-each-group&gt; 更好地表达 说明

    【讨论】: