首页 > 解决方案 > xslt xml表格记录分页

问题描述

我是一个非常简单的 xml 表,其中包含很多需要分页显示的行。我知道以前有人问过这个问题(一种或另一种方式),但从未给出过真正的、好的解决方案。

仅作记录,我认为 xslt 派上用场的真实例子之一是 xslt 分页 - 我不知道原因 - 在网络上的任何地方都没有真正彻底解释。只给出了不完整的、不工作的或一些精巧的例子。完全不满意也没有用。

这就是为什么我刚刚又来这里讨论这件事的原因。我将从一些相当简单的 .xml 示例开始,它以某种方式适合我将在此处进一步介绍的 .xsl 分页示例。

.xml 示例:

<group>
 <item> 01 </item>
 <item> 02 </item>
 <item> 03 </item>
 <item> 04 </item>
 <item> 05 </item>
 <item> 06 </item>
 <item> 07 </item>
 <item> 08 </item>
 <item> 09 </item>
 <item> 10 </item>
 <item> 11 </item>
 <item> 12 </item>
 <item> 13 </item>
 <item> 14 </item>
 <item> 15 </item>
 <item> 16 </item>
 <item> 17 </item>
 <item> 18 </item>
 <item> 19 </item>
 <item> 20 </item>
 <item> 21 </item>
 <item> 22 </item>
 <item> 23 </item>
 <item> 24 </item>
 <item> 25 </item>
 <item> 26 </item>
</group>

和相应的 .xsl (取自某个站点,但为简洁起见截断了部分):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" encoding="UTF-8" omit-xml-declaration="yes"/>
 <xsl:param name="currentPage"/>
 <xsl:template match="/">
 <xsl:variable name="recordsPerPage" select="5"/>
 <xsl:variable name="pageNumber">
  <xsl:choose>
  <!-- first page -->
  <xsl:when test="$currentPage &lt;= 0 or $currentPage = '' or $currentPage = 'NaN'">0</xsl:when>
   <!-- what was passed in -->
  <xsl:otherwise>
  <xsl:value-of select="$currentPage"/>
 </xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="numberOfRecords" select="count(/group/item)"/>
<!-- The fun starts here --> 
<ul class="listing self-clear">
 <xsl:for-each select="//item">
  <xsl:if test="position() &gt; $recordsPerPage * number($pageNumber) and position() &lt;= number($recordsPerPage * number($pageNumber) + $recordsPerPage )">
  <li>
   <xsl:attribute name="class">
     <xsl:if test="position() = $recordsPerPage * (number($pageNumber) + 1)">last</xsl:if>
     </xsl:attribute>
      <h4> <xsl:value-of select="text()"/> </h4>
  </li>
 </xsl:if>
 </xsl:for-each>
</ul>
<xsl:call-template name="pagination">
<xsl:with-param name="pageNumber" select="$pageNumber"/>
<xsl:with-param name="recordsPerPage" select="$recordsPerPage"/>
<xsl:with-param name="numberOfRecords" select="$numberOfRecords"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="pagination">
  <xsl:param name="pageNumber"/>
  <xsl:param name="recordsPerPage"/>
  <xsl:param name="numberOfRecords"/>
<div class="pagination">
<div class="wrapper">
 <xsl:if test="(($pageNumber +1) * $recordsPerPage) &lt; ($numberOfRecords)">
  <a href="?page={$pageNumber + 1}" class="next">Next</a>
 </xsl:if>
 <span class="page-nos">Page </span>
  <xsl:if test="$pageNumber &gt; 0">
   <a href="?page={$pageNumber - 1}" class="prev">Prev</a>
  </xsl:if>
 </div>
</div>
</xsl:template>
</xsl:stylesheet>

这种风格实际上是行不通的。正如它“部分”所做的那样。整个过程是不完整的,因此被错误地显示。

我需要这个解决方案工作:

第一页 上一页 x / y 下一页 最后一页

在这里,我只是放了一些工作小提琴示例,以供人们准确理解我(真正)的意思:

https://jsfiddle.net/MrcaS48/2e9kq3v0/

标签: xmlxslt

解决方案


如果我猜对了(!),您想将这些项目分成大小相等的组。这可以很简单地实现:

XSLT 1.0

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:variable name="groupSize" select="5" />

<xsl:template match="/group">
    <html>
        <body>
            <!-- select  every first item in a group -->
            <xsl:apply-templates select="item[position() mod $groupSize = 1]" />
        </body>
    </html>
</xsl:template>

<xsl:template match="item">
    <div id="set{position()}">
        <ul>
            <!-- list self and following siblings within this group -->
            <xsl:apply-templates select=". | following-sibling::item[position() &lt; $groupSize]" mode="item" />        
        </ul>
    </div>
</xsl:template>

<xsl:template match="item" mode="item">
    <li>
        <xsl:value-of select="."/>
    </li>
</xsl:template>

</xsl:stylesheet>

应用于您的输入示例,结果将是:

结果

<html>
  <body>
    <div id="set1">
      <ul>
        <li> 01 </li>
        <li> 02 </li>
        <li> 03 </li>
        <li> 04 </li>
        <li> 05 </li>
      </ul>
    </div>
    <div id="set2">
      <ul>
        <li> 06 </li>
        <li> 07 </li>
        <li> 08 </li>
        <li> 09 </li>
        <li> 10 </li>
      </ul>
    </div>
    <div id="set3">
      <ul>
        <li> 11 </li>
        <li> 12 </li>
        <li> 13 </li>
        <li> 14 </li>
        <li> 15 </li>
      </ul>
    </div>
    <div id="set4">
      <ul>
        <li> 16 </li>
        <li> 17 </li>
        <li> 18 </li>
        <li> 19 </li>
        <li> 20 </li>
      </ul>
    </div>
    <div id="set5">
      <ul>
        <li> 21 </li>
        <li> 22 </li>
        <li> 23 </li>
        <li> 24 </li>
        <li> 25 </li>
      </ul>
    </div>
    <div id="set6">
      <ul>
        <li> 26 </li>
      </ul>
    </div>
  </body>
</html>

推荐阅读