simple xsl issue with if statement inside for-each

2020-04-21 06:12发布

问题:

Here is my code

    <table cellspacing="0" cellpadding="0"><tbody>
    <tr>
    <xsl:for-each select="/*/nearme/location">
    <td>
    <input type="radio" name="rf" id="rf" class="page_checkbox"/><label for="rf1"><span></span><xsl:value-of select="."/></label>
    </td>
    <xsl:if test="position() mod 5=0">
    </tr><tr>
    </xsl:if>
    </xsl:for-each>
    </tr>
    </tbody></table>

If you look there is an xsl if test that determines if the position is modulus 5. When it does, i want to end the tr and start a new tr however it breaks with this current code.

Any idea how to solve this?

UPDATE:

Here is my xml:

     <nearme>

     <location id="538">Pleasures</location>

     <location id="541">Baby Dolls</location>

     <location id="1521">Michelle's Beach House</location>

     <location id="1886">Wild Wild West Gentlemen's Club</location>

     <location id="993">Sadies</location>

     <location id="5381">ABC</location>

     <location id="541">DEF</location>

     <location id="1521">ghi</location>

     <location id="1886">FDFFDSFD</location>

     <location id="993">HGHHFH</location>

    </nearme>

And here is my expected output:

<table cellspacing="0" cellpadding="0"><tbody>
        <tr>
        <td>
        <input type="radio" name="rf" id="rf1" class="page_checkbox"/><label for="rf1"><span></span>Pleasures</label>
        </td>
        <td>
        <input type="radio" name="rf" id="rf2" class="page_checkbox"/><label for="rf2"><span></span>Baby Dolls</label>
        </td>
        <td>
        <input type="radio" name="rf" id="rf3" class="page_checkbox"/><label for="rf3"><span></span>Michelle's Beach House</label>
        </td>
        <td>
        <input type="radio" name="rf" id="rf4" class="page_checkbox"/><label for="rf4"><span></span>Wild Wild West Gentlemen's Club</label>
        </td>
        <td>
        <input type="radio" name="rf" id="rf5" class="page_checkbox"/><label for="rf5"><span></span>Sadies</label>
        </td>
        </tr>
        <tr>        
        <td>
        <input type="radio" name="rf" id="rf6" class="page_checkbox"/><label for="rf6"><span></span>ABC</label>
        </td>
        <td>
        <input type="radio" name="rf" id="rf7" class="page_checkbox"/><label for="rf7"><span></span>DEF</label>
        </td>
        <td>
        <input type="radio" name="rf" id="rf8" class="page_checkbox"/><label for="rf8"><span></span>ghi</label>
        </td>
        <td>
        <input type="radio" name="rf" id="rf9" class="page_checkbox"/><label for="rf9"><span></span>FDFFDSFD</label>
        </td>
        <td>
        <input type="radio" name="rf" id="rf10" class="page_checkbox"/><label for="rf10"><span></span>HGHHFH</label>
        </td>
        </tr>
        </tbody></table>

回答1:

To simplify the example to the minimum necessary to demonstrate the problem, consider the following:

XML

<nearme>
  <location id="1">A</location>
  <location id="2">B</location>
  <location id="3">C</location>
  <location id="4">D</location>
  <location id="5">E</location>
  <location id="6">F</location>
  <location id="7">G</location>
  <location id="8">H</location>
  <location id="9">I</location>
  <location id="10">J</location>
  <location id="11">K</location>
  <location id="12">L</location>
</nearme>

XSLT 1.0

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:template match="/nearme">
    <table border="1">
        <!-- a row for every group of 5 items -->
        <xsl:for-each select="location[position() mod 5 = 1]">
            <tr>
                <!-- a cell for every item in the current group of 5 -->
                <xsl:for-each select=". | following-sibling::location[position() &lt; 5]">
                    <td>
                        <xsl:value-of select="."/>
                    </td>
                </xsl:for-each>
            </tr>
        </xsl:for-each>
    </table>
</xsl:template>

</xsl:stylesheet>

Result

<table border="1">
  <tr>
    <td>A</td>
    <td>B</td>
    <td>C</td>
    <td>D</td>
    <td>E</td>
  </tr>
  <tr>
    <td>F</td>
    <td>G</td>
    <td>H</td>
    <td>I</td>
    <td>J</td>
  </tr>
  <tr>
    <td>K</td>
    <td>L</td>
  </tr>
</table>


回答2:

You have to use grouping.

In XSLT 2.0 you can use for-each-group, grouping by 5 adjacent location elements.

For each of the above groups generate a tr element.

Inside it you must place a loop iterating through the current group, generating td elements, with radio and label inside.

Below you have an example code:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />
  <xsl:strip-space elements="*"/>

  <xsl:template match="/">
    <table cellspacing="0" cellpadding="0"><tbody>
      <xsl:for-each-group select="*/nearme/location" group-by="floor((position() - 1) div 5)">
        <tr>
        <xsl:for-each select="current-group()">
          <td>
          <input type="radio" name="rf" id="rf" class="page_checkbox"/>
            <label for="rf1"><span><xsl:value-of select="."/></span></label>
          </td>
        </xsl:for-each>
        </tr>
      </xsl:for-each-group>
    </tbody></table>
  </xsl:template>
</xsl:stylesheet>


标签: xslt