XSLT - build multiple (n) html tables of equal size (in this case, 3x3)

会有一股神秘感。 提交于 2019-12-04 19:45:26

Update: Refactored

This stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:param name="pRows" select="3"/>
    <xsl:param name="pColumns" select="3"/>
    <xsl:template match="/" name="tables">
        <xsl:param name="pSequence" select="*/*"/>
        <xsl:variable name="vSize" select="$pRows * $pColumns"/>
        <xsl:for-each select="$pSequence[position() mod $vSize = 1]">
            <xsl:variable name="vPosition" select="position()"/>
            <table>
                <xsl:call-template name="rows">
                    <xsl:with-param name="pSequence"
                         select="$pSequence[
                                    position() > ($vPosition - 1) * $vSize
                                     and
                                    $vPosition * $vSize + 1 > position()
                                 ]"/>
                </xsl:call-template>
            </table>
        </xsl:for-each>
    </xsl:template>
    <xsl:template name="rows">
        <xsl:param name="pSequence" select="/.."/>
        <xsl:param name="pRow" select="$pRows"/>
        <xsl:if test="$pRow">
            <xsl:call-template name="rows">
                <xsl:with-param name="pSequence" select="$pSequence"/>
                <xsl:with-param name="pRow" select="$pRow - 1"/>
            </xsl:call-template>
            <tr>
                <xsl:call-template name="columns">
                    <xsl:with-param name="pSequence"
                         select="$pSequence[
                                    position() > ($pRow - 1) * $pColumns
                                     and
                                    $pRow * $pColumns + 1 > position()
                                 ]"/>
                </xsl:call-template>
            </tr>
        </xsl:if>
    </xsl:template>
    <xsl:template name="columns">
        <xsl:param name="pSequence" select="/.."/>
        <xsl:param name="pColumn" select="$pColumns"/>
        <xsl:if test="$pColumn">
            <xsl:call-template name="columns">
                <xsl:with-param name="pSequence" select="$pSequence"/>
                <xsl:with-param name="pColumn" select="$pColumn - 1"/>
            </xsl:call-template>
            <td>
                <xsl:apply-templates select="$pSequence[$pColumn]"/>
            </td>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

Input:

<root>
    <item>1</item>
    <item>2</item>
    <item>3</item>
    <item>4</item>
    <item>5</item>
    <item>6</item>
    <item>7</item>
    <item>8</item>
    <item>9</item>
    <item>10</item>
    <item>11</item>
    <item>12</item>
    <item>13</item>
    <item>14</item>
    <item>15</item>
    <item>16</item>
</root>

Output:

<table>
    <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
    </tr>
    <tr>
        <td>4</td>
        <td>5</td>
        <td>6</td>
    </tr>
    <tr>
        <td>7</td>
        <td>8</td>
        <td>9</td>
    </tr>
</table>
<table>
    <tr>
        <td>10</td>
        <td>11</td>
        <td>12</td>
    </tr>
    <tr>
        <td>13</td>
        <td>14</td>
        <td>15</td>
    </tr>
    <tr>
        <td>16</td>
        <td></td>
        <td></td>
    </tr>
</table>

Note: It looks like is following a pattern... I might be missing something. I'll revisite this.

EDIT: This stylesheet importing the former (just to show that there are no modifications)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:import href="table.xsl"/>
    <xsl:output method="html"/>
    <xsl:template match="/">
        <xsl:call-template name="tables">
            <xsl:with-param name="pSequence"
                 select="xml/dsQueryResponse/Rows/Row[position()!=1]"/>
        </xsl:call-template>
    </xsl:template>
    <xsl:template match="Row">
        <xsl:value-of select="@Title"/>
    </xsl:template>
</xsl:stylesheet>

With this input:

<xml>
    <dsQueryResponse>
        <x:schema xmlns:x="x"></x:schema>
        <Rows>
            <Row Title="Title 1" ID="33"/>
            <Row Title="Title 2" ID="32"/>
            <Row Title="Title 3" ID="31"/>
            <Row Title="Title 4" ID="30"/>
            <Row Title="Title 5" ID="29"/>
            <Row Title="Title 6" ID="28"/>
            <Row Title="Title 7" ID="27"/>
            <Row Title="Title 8" ID="24"/>
            <Row Title="Title 9" ID="20"/>
            <Row Title="Title 10" ID="19"/>
            <Row Title="Title 11" ID="17"/>
            <Row Title="Title 12" ID="132"/>
            <Row Title="Title 13" ID="131"/>
            <Row Title="Title 14" ID="130"/>
            <Row Title="Title 15" ID="129"/>
            <Row Title="Title 16" ID="128"/>
            <Row Title="Title 17" ID="127"/>
            <Row Title="Title 18" ID="124"/>
            <Row Title="Title 19" ID="120"/>
            <Row Title="Title 20" ID="119"/>
            <Row Title="Title 21" ID="117"/>
        </Rows>
    </dsQueryResponse>
</xml>

Output:

<table>
   <tr>
      <td>Title 2</td>
      <td>Title 3</td>
      <td>Title 4</td>
   </tr>
   <tr>
      <td>Title 5</td>
      <td>Title 6</td>
      <td>Title 7</td>
   </tr>
   <tr>
      <td>Title 8</td>
      <td>Title 9</td>
      <td>Title 10</td>
   </tr>
</table>
<table>
   <tr>
      <td>Title 11</td>
      <td>Title 12</td>
      <td>Title 13</td>
   </tr>
   <tr>
      <td>Title 14</td>
      <td>Title 15</td>
      <td>Title 16</td>
   </tr>
   <tr>
      <td>Title 17</td>
      <td>Title 18</td>
      <td>Title 19</td>
   </tr>
</table>
<table>
   <tr>
      <td>Title 20</td>
      <td>Title 21</td>
      <td></td>
   </tr>
   <tr>
      <td></td>
      <td></td>
      <td></td>
   </tr>
   <tr>
      <td></td>
      <td></td>
      <td></td>
   </tr>
</table>

Note: Using xsl:apply-templates is more flexible than xsl:value-of.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!