如何在href上使用xslt实现排序

时间:2010-08-24 04:13:27

标签: xslt

我正在使用xslt,我想在我的href链接上实现排序。

下面是我需要实现排序的xslt部分。

     <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:tlink="urn:TridionLinking" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:utils="urn:XSLTExtensions" exclude-result-prefixes="xsl xlink tlink msxsl utils">
  <xsl:output method="xml" version="1.0" encoding="UTF-8" omit-xml-declaration="yes" />
  <!--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        Title:              View All the Destinations XHTML
        Description:  Render view all the destinations control
        Author:           Manoj Singh
    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-->
  <xsl:include href="dynamic_linking.xslt"/>

  <!-- Translations are still loaded here because of XHTML content, research a way around that -->
  <xsl:key name="kCityById" match="city" use="@id"/>
  <xsl:variable name="vLocations" select="document(concat($publicationPath, /list/resources/@location))/list"/>
  <xsl:variable name="destination" select="/list"/>
  <xsl:param name="publicationPath"/>
  <xsl:param name="pubURL"/>
  <xsl:param name="pageURL"/>

  <xsl:param name="region"/>
  <xsl:param name="country"/>


  <!-- offset controls the starting position of the results to show -->
  <xsl:param name="offset">0</xsl:param>
  <!-- blockSize controls how many results to show on a single page -->
  <xsl:param name="blockSize" select="15" />

  <!-- Amount of page links to show by default -->
  <xsl:param name="pagesShown">20</xsl:param>

  <xsl:variable name="totalHits" select="count(/list/destination[contains(concat($pubURL,@url),substring-before($pageURL,'/index.aspx'))])" />

  <xsl:template name="calcStart">
    <xsl:choose>
      <xsl:when test="$offset = 0">1</xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="($offset * $blockSize) + 1"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template name="calcEnd">
    <xsl:choose>
      <xsl:when test="(($offset + 1) * $blockSize) > $totalHits">
        <xsl:value-of select="$totalHits"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="($offset + 1) * $blockSize"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  <xsl:template name="pageNavigation">
    <xsl:param name="pageCount"/>
    <xsl:param name="currPage"/>
    <xsl:param name="showPages">
      <xsl:choose>
        <xsl:when test="$pagesShown > $pageCount">
          <xsl:value-of select="$pageCount"/>
        </xsl:when>
        <xsl:when test="($pagesShown mod 2) = 0">
          <xsl:value-of select="$pagesShown"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$pagesShown + 1"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:param>
    <xsl:param name="currEntry" select="1"/>
    <xsl:param name="offset">
      <xsl:choose>
        <xsl:when test="($currPage &lt; $showPages) or ($pageCount = 1)">0</xsl:when>
        <xsl:when test="$currPage > ($pageCount - $showPages + 1)">
          <xsl:value-of select="$pageCount - $showPages"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$currPage - ($showPages div 2) - 1"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:param>

    <!-- Header Processing -->
    <xsl:if test="$currEntry = 1">
      <xsl:if test="($pageCount > $showPages) and ($currPage >= $showPages)">
        <li>... </li>
      </xsl:if>
    </xsl:if>

    <xsl:if test="not ($currEntry > $showPages)">
      <li>
        <xsl:choose>
          <xsl:when test="($currEntry + $offset) = $currPage">
            <strong class="thisPage">
              <xsl:value-of select="$currEntry + $offset"/>
            </strong>
          </xsl:when>
          <xsl:otherwise>
            <a href="{utils:GetHashedUrl(concat($pageURL,'?offset=',$currEntry + $offset - 1,'&amp;blockSize=',$blockSize,'&amp;pagesShown=',$pagesShown))}">
              <xsl:value-of select="$currEntry + $offset"/>
            </a>
          </xsl:otherwise>
        </xsl:choose>
      </li>

      <xsl:if test="not ($currEntry >=  $showPages)">
        <li class="separatorLine">|</li>
      </xsl:if>

      <xsl:call-template name="pageNavigation">
        <xsl:with-param name="pageCount" select="$pageCount"/>
        <xsl:with-param name="currPage" select="$currPage"/>
        <xsl:with-param name="showPages" select="$showPages"/>
        <xsl:with-param name="currEntry" select="$currEntry + 1"/>
        <xsl:with-param name="offset" select="$offset"/>
      </xsl:call-template>
    </xsl:if>

    <!-- Footer Processing -->
    <xsl:if test="$currEntry = 1">
      <xsl:if test="($pageCount > $showPages) and (($pageCount - $currPage + 1) >= $showPages)">
        <li> ...</li>
      </xsl:if>
    </xsl:if>
  </xsl:template>

  <xsl:template name="displayPageNavigation">
    <div class="continueBar">
      <div class="continueBarLeft">
        <xsl:variable name="displayStart">
          <xsl:call-template name="calcStart"/>
        </xsl:variable>
        <xsl:variable name="displayEnd">
          <xsl:call-template name="calcEnd"/>
        </xsl:variable>
        <strong>
          <xsl:value-of select="utils:TextFormatted('DisplayingDestinations2Arg', concat($displayStart, '-', $displayEnd), $totalHits)"/>
        </strong>
      </div>
      <div class="continueBarRight">
        <ul class="paginationLinks">
          <!-- Show a back button when available -->
          <xsl:choose>
            <xsl:when test="$offset > 0">
              <li class="noBorder first">
                <a class="iconButtonBackBar" href="{$pageURL}?offset={$offset - 1}&amp;blockSize={$blockSize}&amp;pagesShown={$pagesShown}">
                  <xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
                </a>
              </li>
            </xsl:when>
            <xsl:otherwise>
              <li class="noBorder first">
                <span class="iconButtonBackBarOff">
                  <xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
                </span>
              </li>
            </xsl:otherwise>
          </xsl:choose>

          <!-- Output the page navigation links -->
          <xsl:call-template name="pageNavigation">
            <xsl:with-param name="pageCount">
              <xsl:choose>
                <xsl:when test="$blockSize >= $totalHits">1</xsl:when>
                <xsl:when test="($totalHits mod $blockSize) != 0">
                  <xsl:value-of select="ceiling($totalHits div $blockSize)"/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="$totalHits div $blockSize"/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:with-param>
            <xsl:with-param name="currPage" select="$offset + 1"/>
          </xsl:call-template>

          <!-- Show a next button when available -->
          <xsl:choose>
            <xsl:when test="(($offset + 1) * $blockSize) > $totalHits">
              <li class="last">
                <span class="iconButtonForwardBarOff">
                  <xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
                </span>
              </li>
            </xsl:when>
            <xsl:otherwise>
              <li class="last">
                <a class="iconButtonForwardBar" href="{$pageURL}?offset={$offset + 1}&amp;blockSize={$blockSize}&amp;pagesShown={$pagesShown}">
                  <xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
                </a>
              </li>
            </xsl:otherwise>
          </xsl:choose>
        </ul>
      </div>

      <div class="clearBoth">
        <xsl:comment/>
      </div>
    </div>
  </xsl:template>

  <!-- root match -->
  <xsl:template match="/list">
    <!--<xsl:value-of select="$publicationPath"/>-->
    <div class="brownBarContainer">
      <div class="brownBar">
        All Destinations
      </div>
    </div>
    <table width="100%" cellspacing="0" cellpadding="0" border="0" class="displayTable">
      <tbody>
        <tr>
          <th scope="col" class="first sortSelected">
            <div class="thPadding">              
              <xsl:element name="a">
                <xsl:attribute name="href"></xsl:attribute>                
                <xsl:attribute name="class">iconDownSortArrow</xsl:attribute>                
              </xsl:element>Destination
            </div>
          </th>
          <th scope="col" class="sortHover">
            <div class="thPadding">         
              <xsl:element name="a">
                <xsl:attribute name="href"></xsl:attribute>
                <xsl:attribute name="class">iconSortArrowOff</xsl:attribute>
              </xsl:element>Country
            </div>
          </th>
          <th scope="col" class="sortHover">
            <div class="thPadding">            
              <xsl:element name="a">
                <xsl:attribute name="href"></xsl:attribute>
                <xsl:attribute name="class">iconSortArrowOff</xsl:attribute>
              </xsl:element>Region
            </div>
          </th>
        </tr>
        <xsl:choose>
          <xsl:when test="$region='' and $country=''">
            <xsl:apply-templates select="destination">
              <xsl:sort select="@title" order="ascending" />
            </xsl:apply-templates>          
          </xsl:when>
          <xsl:when test="$country!=''">
            <xsl:apply-templates select="destination[city/@id=$vLocations/region/country[@id=$country]/city/@id]">
              <xsl:sort select="@title" order="ascending" />
            </xsl:apply-templates>
          </xsl:when>
          <xsl:when test="$region!=''">
            <xsl:apply-templates select="destination[city/@id=$vLocations/region[@id=$region]/country/city/@id]">
              <xsl:sort select="@title" order="ascending" />
            </xsl:apply-templates>
          </xsl:when>
        </xsl:choose>
      </tbody>
    </table>
    <div class="horRuleWhite">
      <hr/>
    </div>
    <xsl:call-template name="displayPageNavigation" />
  </xsl:template>
  <xsl:template match="text()"/>
  <xsl:template match="destination">
    <xsl:variable name="vReverseURL">
      <xsl:call-template name="reverse">
        <xsl:with-param name="string" select="@url"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="vCountryURL">
      <xsl:call-template name="reverse">
        <xsl:with-param name="string" select="substring-after($vReverseURL,'/')"/>
      </xsl:call-template>
      <xsl:text>/index.aspx</xsl:text>
    </xsl:variable>
    <xsl:variable name="vRegionURL">
      <xsl:call-template name="reverse">
        <xsl:with-param name="string" select="substring-after(substring-after($vReverseURL,'/'),'/')"/>
      </xsl:call-template>
      <xsl:text>/index.aspx</xsl:text>
    </xsl:variable>
    <xsl:variable name="current" select="."/>    
    <xsl:for-each select="$vLocations">   
      <tr>
        <td class="detail first">          
          <a class="arrowSmallFront" href="{$current/@url}">           
            <xsl:value-of select="$current/@title"/>
          </a>
        </td>
        <td class="detail noLeftBorder">
          <a class="arrowSmallFront" href="{$vCountryURL}">
            <xsl:value-of select="key('kCityById',$current/city/@id)/../@name"/>
          </a>
        </td>
        <td class="detail noLeftBorder">
          <a class="arrowSmallFront" href="{$vRegionURL}">
            <xsl:value-of select="key('kCityById',$current/city/@id)/../../@name"/>
          </a>
        </td>
      </tr>
    </xsl:for-each>
  </xsl:template>
  <xsl:template name="reverse">
    <xsl:param name="string" select="''"/>
    <xsl:if test="$string != ''">
      <xsl:call-template name="reverse">
        <xsl:with-param name="string" select="substring($string,2)"/>
      </xsl:call-template>
      <xsl:value-of select="substring($string,1,1)"/>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

现在一切正常,但是我想在xslt上面的href链接上实现排序。

 <tr>
  <th scope="col" class="first sortSelected">
    <div class="thPadding">              
      <xsl:element name="a">
        <xsl:attribute name="href"></xsl:attribute>                
        <xsl:attribute name="class">iconDownSortArrow</xsl:attribute>                
      </xsl:element>Destination
    </div>
  </th>
  <th scope="col" class="sortHover">
    <div class="thPadding">         
      <xsl:element name="a">
        <xsl:attribute name="href"></xsl:attribute>
        <xsl:attribute name="class">iconSortArrowOff</xsl:attribute>
      </xsl:element>Country
    </div>
  </th>
  <th scope="col" class="sortHover">
    <div class="thPadding">            
      <xsl:element name="a">
        <xsl:attribute name="href"></xsl:attribute>
        <xsl:attribute name="class">iconSortArrowOff</xsl:attribute>
      </xsl:element>Region
    </div>
  </th>
</tr>

1)Destinations.xml

<?xml version="1.0"?>
<list type="Destinations">
<resources location="include/xml/locations.xml">
<publication>481</publication>
</resources>
<destination id="594051" title="Sydney" url="/asiapacific/australia/sydney.aspx" >
<city id="192409" />
</destination>
<destination id="594088" title="Brisbane" url="/asiapacific/australia/brisbane.aspx" >
<city id="192397" />
</destination>
<destination id="594579" title="Dubai" url="/middleeast/uae/dubai.aspx" >
<city id="192855" />
</destination>
<destination id="594580" title="Abu Dhabi" url="/middleeast/uae/abudhabi.aspx" >
<city id="192851" />
</destination>
</list>

2)Locations.xml

<?xml version="1.0"?>
<list type="Locations">
<region id="192393" code="ASIA" name="Asia &amp; the Pacific" shortname="Asia &amp; the Pacific">
<country id="192395" code="AU" name="Australia" shortname="Australia">
<city id="192397" code="BNE" name="Brisbane" shortname="Brisbane">
<airport id="192399" code="BNE" name="Brisbane International Airport" shortname="Brisbane"></airport>
</city>
<city id="192409" code="SYD" name="Sydney" shortname="Sydney">
<airport id="192411" code="SYD" name="Kingsford Smith Airport" shortname="Sydney"></airport>
</city>
</country>
</region>
<region id="192847" code="MEAF" name="The Middle East &amp; Africa" shortname="The Middle East &amp; Africa">
<country id="192849" code="AE" name="United Arab Emirates" shortname="United Arab Emirates">
<city id="192851" code="AUH" name="Abu Dhabi" shortname="Abu Dhabi">
<airport id="192853" code="AUH" name="Abu Dhabi" shortname="Abu Dhabi"></airport>
</city>
<city id="192855" code="DXB" name="Dubai" shortname="Dubai">
<airport id="192857" code="DXB" name="Dubai International Airport" shortname="Dubai"></airport>
</city>
</country>
</region>
</list>

请建议!

感谢。

1 个答案:

答案 0 :(得分:1)

在每个关闭代码</xsl:apply-templates>之前,您需要添加<xsl:sort>,例如

      <xsl:when test="$region='' and $country=''">
        <xsl:apply-templates select="destination">
          <xsl:sort select="@href" />
        </xsl:apply-templates>          
      </xsl:when>

上面的代码假设@href是目标元素的属性,但这只是一个猜测,因为你没有告诉我们@href在输入中出现的位置。除非我错过了什么。

如果您需要进一步的帮助,请发布输入XML样本。

在第二次阅读时,我想知道你是否想要根据点击的三个元素中的哪一个进行排序?请澄清并编辑您的问题,以包含输入XML的示例。

好的,根据您的评论,很明显您要根据用户最后点击的列进行排序。

为了扩展Alejandro所说的内容,交互行为超出了XSLT的范围。如果希望XSLT根据不同的列进行排序,则需要将该列作为初始参数传递给XSLT。如果XSLT在服务器上运行,则在更改表的排序顺序时将重新加载整个页面。你想要吗?

对于即时排序,你可以在客户端的js中调用XSLT,但这有点毛茸茸。通常用于交互式排序,人们只需直接在javascript中排序。以下是一些教程和实现: