简体   繁体   中英

XSLT for-each loop and formatting table rows

How could I modify the xsl below so that in the for-each loop that is placing images puts 2 images per table row, rather than 4 (what it currently does).

I believe it has to do with the mod function?

I tried splitting the foreach sibling loop onto another row but then only the first image shows up on the first row and the rest on a second row.

<xsl:for-each select="Finding">
  <xsl:if test="FindingType = 'A'">
  <xsl:variable name="nImage" select="count(Image)" />
    <tr><td class="di"><table width="100%" class="findings">
  <tr><td class="shade" colspan="4"><p class="g"><b>Finding</b></p></td></tr>
  <xsl:for-each select="Image[position() mod 4 = 1]">
<tr><td width="25%" align="left" valign="top"><p class="g"><img src="{.}" height="128" width="128" hspace="12"/><br />
    <xsl:value-of select="@Type" /><xsl:text> </xsl:text>    <xsl:value-of select="@SubType" />
    <xsl:if test="@Position != ''"> (<xsl:value-of select="@Position" />)         </xsl:if><br /><br />
</p>
    </td></tr>
<tr><xsl:for-each select=". | following-sibling::Image[position() &lt; 4 and (position() mod 4 = 0 or position() mod 4 = 1 or position() mod 4 = 2)]">
    <td width="25%" valign="top" align="left"><p class="g">
    <xsl:if test="(string-length(following-sibling::Image/.) > 0)">
    <img src="{following-sibling::Image/.}" height="128" width="128" hspace="12" />
    </xsl:if>
    <br />
        <xsl:value-of select="following-sibling::Image/@Type" />        <xsl:text> </xsl:text>    
    <xsl:value-of select="following-sibling::Image/@SubType" />
        <xsl:if test="following-sibling::Image/@Position != ''"> (<xsl:value-of select="following-sibling::Image/@Position" />)         </xsl:if>
<br /><br /></p>
</td>
</xsl:for-each>
  <xsl:if test="$nImage = 2">
    <td width="25%" />
  </xsl:if>
</tr>

The answer is simple : Replace 4 by 2 , or even better, define a global, parameter pNumCols with value 2 .

You will have the following changes:

  1. Add this line at global level: <xsl:param name="pNumCols" select="2"/>

  2. Replace :

    <xsl:for-each select="Image[position() mod 4 = 1]">

with

<xsl:for-each select="Image[position() mod $pNumCols = 1]">

.3. Replace :

<xsl:for-each select=". | following-sibling::Image
              [position() &lt; 4 
             and (position() mod 4 = 0 or position() mod 4 = 1 
                 or position() mod 4 = 2)]">

with:

<xsl:for-each select=". | following-sibling::Image
                               [not(position() >= $pNumCols)]">

Do note :

<xsl:for-each select=". | following-sibling::Image
              [position() &lt; 4 
             and (position() mod 4 = 0 or position() mod 4 = 1 
                 or position() mod 4 = 2)]">

is equivalent to the shorter:

<xsl:for-each select=". | following-sibling::Image[position() &lt; 4 ]">

Yes, you should change Image[position() mod 4 = 1] to use 2 instead of 4. And below . | following-sibling::Image[position() < 4 and (position() mod 4 = 0 or position() mod 4 = 1 or position() mod 4 = 2)] . | following-sibling::Image[position() < 4 and (position() mod 4 = 0 or position() mod 4 = 1 or position() mod 4 = 2)] . | following-sibling::Image[position() < 4 and (position() mod 4 = 0 or position() mod 4 = 1 or position() mod 4 = 2)] becomes . | following-sibling::Image[position() < 2 and (position() mod 2 = 0)] . | following-sibling::Image[position() < 2 and (position() mod 2 = 0)] . | following-sibling::Image[position() < 2 and (position() mod 2 = 0)] .

That should be enough.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM