Home > Software design >  XSLT dynamic table creation
XSLT dynamic table creation

Time:08-18

My goal is to transform an xml file to an html file, and style its contents as a table. However, I only want exactly four elements per row, and I can't seem to find a wayon how to achieve this.

members.xml:

<?xml version = "1.0"?> 
<?xml-stylesheet type = "text/xsl" href = "/teammembers_imports.xsl"?> 
<team>
    <heading>TEST TEAM</heading>
    <member>
        <name>Max Mustermann</name>
        <role>Product Owner</role>
    </member>
    <member>
        <name>Max Mustermann 2</name>
        <role>Product Owner</role>
    </member>
    <member>
        <name>Max Mustermann 3</name>
        <role>Product Owner</role>
    </member>
    <member>
        <name>Max Mustermann 4</name>
        <role>Product Owner</role>
    </member>
    <member>
        <name>Max Mustermann 5</name>
        <role>Product Owner</role>
    </member>
</team>

teammembers_imports.xsl:

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

    <xsl:template match = "/">
      <html>
        <body>
          <table>
            <xsl:apply-templates/>
          </table>
        </body>
      </html>
    </xsl:template>
    
    <xsl:template match="member">
      <td>
        <xsl:value-of select="name"/>
      </td>
    </xsl:template>
  </xsl:stylesheet>

CodePudding user response:

Assuming you want a result that looks like: enter image description here

you could do:

XSLT 1.0

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

<xsl:template match="/team">
    <html>
        <body>
            <table border="1">
                <xsl:for-each select="member[position() mod 4 = 1]">
                    <tr>
                        <td>
                            <xsl:value-of select="name"/>
                        </td>
                        <td>
                            <xsl:value-of select="following-sibling::member[1]/name"/>
                        </td>
                        <td>
                            <xsl:value-of select="following-sibling::member[2]/name"/>
                        </td>
                        <td>
                            <xsl:value-of select="following-sibling::member[3]/name"/>
                        </td>
                    </tr>
                </xsl:for-each>
            </table>
        </body>
    </html>
</xsl:template>

</xsl:stylesheet>

Alternatively you could do:

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

<xsl:template match="/team">
    <html>
        <body>
            <table border="1">
                <xsl:for-each select="member[position() mod 4 = 1]">
                    <tr>
                        <xsl:for-each select=". | following-sibling::member[position() &lt; 4]">
                            <td>
                                <xsl:value-of select="name"/>
                            </td>
                        </xsl:for-each>
                    </tr>
                </xsl:for-each>
            </table>
        </body>
    </html>
</xsl:template>

</xsl:stylesheet>

but the result will not look the same for the last, incomplete, row.

  • Related