meetsur
meetsur

Reputation: 75

XSLT Create HTML Table for Dynamic XML Columns

I am working on putting a xml data into html table. I am new to xslt and trying to get this done. I have xml with dynamic # of columns in specific format * The xml has first two fixed columns ID and ItemNum * Then next columns are in set of 3 and name of the columns can be changed; in a set first column name has to go in header row 2nd is background color for cell and 3rd is border color for a cell

XML document: (can have multiple rows and multiple set of columns)

    <?xml version="1.0" encoding="UTF-8" ?> 
<Rowsets DateCreated="2013-11-16T19:19:22" EndDate="2013-11-16T19:19:22" StartDate="2013-11-16T18:19:22" Version="12.1.4 Build(53)">
<Rowset>
    <Columns>
      <Column Description="ID"  /> 
      <Column Description="ItemNum"  /> 
      <Column Description="Column1Name"  /> 
      <Column Description="Column1NameBkgdColor"  /> 
      <Column Description="Column1NameBorderColor"  /> 
      <Column Description="Column2Name"  /> 
      <Column Description="Column2NameBkgdColor"  /> 
      <Column Description="Column2NameBorderColor"  /> 
    </Columns>
    <Row>
      <ID>1</ID> 
      <ItemNum>Item01</ItemNum> 
      <Column1Name>DataA1</Column1Name> 
      <Column1NameBkgdColor>#FFFFFF</Column1NameBkgdColor> 
      <Column1NameBorderColor>#000000</Column1NameBorderColor> 
      <Column2Name>DataB1</Column2Name> 
      <Column2NameBkgdColor>#3366FF</Column2NameBkgdColor> 
      <Column2NameBorderColor>#000000</Column2NameBorderColor> 
    </Row>
    <Row>
      <ID>2</ID> 
      <ItemNum>Item02</ItemNum> 
      <Column1Name>DataA2</Column1Name> 
      <Column1NameBkgdColor>#3366FF</Column1NameBkgdColor> 
      <Column1NameBorderColor>#FF66FF</Column1NameBorderColor> 
      <Column2Name>DataB2</Column2Name> 
      <Column2NameBkgdColor>#FFFFFF</Column2NameBkgdColor> 
      <Column2NameBorderColor>#FF9933</Column2NameBorderColor> 
    </Row>
  </Rowset>

XSLT I am working on (the column names are hard coded. Need a way so that it can accept dynamic columns):

    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
       <xsl:template match="/">
  <table border="1px">
     <tr>
        <xsl:for-each select="Rowsets/Rowset/Columns/Column">
           <xsl:if test="not(contains(@Description, 'Color'))">
              <td>
                 <xsl:value-of select="@Description"/>
              </td>
           </xsl:if>
        </xsl:for-each>
     </tr>
     <xsl:for-each select="Rowsets/Rowset/Row">
        <tr>
           <td>
              <xsl:value-of select="ID"/>
           </td>
           <td>
              <xsl:value-of select="ItemNum"/>
           </td>
           <td border="1px">
              <xsl:attribute name="bordercolor">
                 <xsl:value-of select="Column1NameBorderColor"/>
              </xsl:attribute>
              <xsl:attribute name="bgcolor">
                 <xsl:value-of select="Column1NameBkgdColor"/>
              </xsl:attribute>
              <xsl:value-of select="Column1Name"/>
           </td>
           <td border="1px">
              <xsl:attribute name="bordercolor">
                 <xsl:value-of select="Column2NameBorderColor"/>
              </xsl:attribute>
              <xsl:attribute name="bgcolor">
                 <xsl:value-of select="Column2NameBkgdColor"/>
              </xsl:attribute>
              <xsl:value-of select="Column2Name"/>
           </td>
        </tr>
     </xsl:for-each>
     <!-- Rowsets/Rowset/Row -->
  </table>

final HTML I am looking for:

   <table border="1px">
   <tr>
   <td>ID</td><td>ItemNum</td><td>Column1Name</td><td>Column2Name</td>
   </tr>
   <tr><td>1</td><td>Item01</td><td border="1px" bordercolor="#000000" bgcolor="#FFFFFF">DataA1</td><td border="1px" bordercolor="#000000" bgcolor="#3366FF">DataB1</td>
   </tr>
   <tr>
   <td>2</td><td>Item02</td><td border="1px" bordercolor="#FF66FF"        bgcolor="#3366FF">DataA2</td><td border="1px" bordercolor="#FF9933" bgcolor="#FFFFFF">DataB2</td>
   </tr>
   <tr>
   tr for additional columns
   <td>multiple tds for set of columns</td>
   </tr>
   </table>

Thanks in advance!

Upvotes: 2

Views: 3761

Answers (1)

Marcus Rickert
Marcus Rickert

Reputation: 4238

The following XSLT 2.0 uses a loop over the columns and the local-name() function to check for the column tags and produce the requested result

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
  <xsl:template match="/">
    <table border="1px">
      <tr>
        <xsl:for-each select="Rowsets/Rowset/Columns/Column">
          <xsl:if test="not(contains(@Description, 'Color'))">
            <td>
              <xsl:value-of select="@Description"/>
            </td>
          </xsl:if>
        </xsl:for-each>
      </tr>

      <xsl:for-each select="Rowsets/Rowset/Row">
        <tr>
          <td>
            <xsl:value-of select="ID"/>
          </td>
          <td>
            <xsl:value-of select="ItemNum"/>
          </td>

          <xsl:variable name="row" select="."/>
          <xsl:for-each select="../Columns/Column">

            <xsl:variable name="columnName" select="@Description"/>

            <xsl:if test="contains($columnName, 'Column') and not(contains($columnName, 'Color'))">
              <td border="1px">
                <xsl:attribute name="bordercolor">
                  <xsl:value-of select="$row/*[name() = concat($columnName, 'BorderColor')]"/>
                </xsl:attribute>
                <xsl:attribute name="bgcolor">
                  <xsl:value-of select="$row/*[name() = concat($columnName, 'BkgdColor')]"/>
                </xsl:attribute>
                <xsl:value-of select="$row/*[name() = $columnName]"/>
              </td>
            </xsl:if>

          </xsl:for-each>

        </tr>
      </xsl:for-each>
      <!-- Rowsets/Rowset/Row -->
    </table>
  </xsl:template>
</xsl:stylesheet>

Upvotes: 2

Related Questions