user2058738
user2058738

Reputation: 369

Creating Separate Tables for each Header/Row in XSLT

I'm new with XML and XSLT.

I have a scenario where I need to create separate tables for each Row element using XSLT.

So far, I have created below XSLT, but it's output is only 1 table.

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="email.xsl" type="text/xsl" ?>
<Rows>

   <Header>
      <SourceTable>SOURCE_TABLE</SourceTable>
      <TargetTable>TARGETTABLE</TargetTable>
   </Header>
   <Row>
      <Fieldname>NAME</Fieldname>
      <Type>Integer</Type>
      <Length>10</Length>
      <Precision>0</Precision>
      <Origin>Target Table Input</Origin>
      <flagfield>changed</flagfield>
   </Row>

   <Header>
      <SourceTable>SOURCE_TABLE</SourceTable>
      <TargetTable>TARGETTABLE</TargetTable>
   </Header>
   <Row>
      <Fieldname>DTIME_INSERTED</Fieldname>
      <Type>Timestamp</Type>
      <Length>6</Length>
      <Precision>-1</Precision>
      <Origin>Source Table Input 2</Origin>
      <flagfield>deleted</flagfield>
   </Row>

</Rows>

XSLT:

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

    <xsl:template match="/Rows">
        <html>
            <body>
                <font size="2" face="Calibri" >
                    <h1>The following Source - Target Tables have DDL Mismatch(es)</h1>
                    <br />

                    <h3>
                        <xsl:for-each select="Header">
                            <xsl:value-of select="SourceTable" />
                        </xsl:for-each>

                        -
                        <xsl:for-each select="Header">
                            <xsl:value-of select="TargetTable" />
                        </xsl:for-each>

                    </h3>

                    <table  border="1px" cellspacing="0" style='font-family:"Courier New", Courier, monospace; font-size:13px'>
                        <tr bgcolor="#9acd32">
                            <th>Fieldname</th>
                            <th>Type</th>
                            <th>Length</th>
                            <th>Precision</th>
                            <th>Origin</th>
                            <th>flagfield</th>
                        </tr>
                        <xsl:for-each select="Row">
                            <tr>
                                <td>
                                    <xsl:value-of select="Fieldname" />
                                </td>
                                <td>
                                    <xsl:value-of select="Type" />
                                </td>
                                <td>
                                    <xsl:value-of select="Length" />
                                </td>
                                <td>
                                    <xsl:value-of select="Precision" />
                                </td>
                                <td>
                                    <xsl:value-of select="Origin" />
                                </td>
                                <td>
                                    <xsl:value-of select="flagfield" />
                                </td>
                            </tr>
                        </xsl:for-each>
                    </table>
                </font>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

The output I'm trying to achive is.

SOURCE_TABLE - TARGETTABLE

Fieldname | Type    |Length |Precision |Origin      | flagfield
Name      | Integer | 10    | 0        |Table Input | changed

SOURCE_TABLE - TARGETTABLE

Fieldname      | Type      |Length | Precision |Origin      | flagfield
DTIME_INSERTED | Timestamp | 6     | -1        |Table Input | deleted

Is this possible?

Upvotes: 0

Views: 255

Answers (1)

zx485
zx485

Reputation: 29052

Even if your requirement seems a little bit odd to me...

where I need to create separate tables for each Row

You can achieve this by splitting your template into two:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" indent="yes" />

    <!-- A template handling the main HTML stuff -->
    <xsl:template match="/Rows">
        <html>
            <body>
                <font size="2" face="Calibri" >
                    <h1>The following Source - Target Tables have DDL Mismatch(es)</h1>
                    <br />
                    <xsl:apply-templates select="Row" />
                </font>
            </body>
        </html>
    </xsl:template>

    <!-- And a template that creates a <table> for each <Row> entry -->
    <xsl:template match="Row">        
        <h3>
            <xsl:for-each select="preceding-sibling::Header[1]">
                <xsl:value-of select="SourceTable" /> - 
                <xsl:value-of select="TargetTable" />
            </xsl:for-each>
        </h3>

        <table  border="1px" cellspacing="0" style='font-family:"Courier New", Courier, monospace; font-size:13px'>
            <tr bgcolor="#9acd32">
                <th>Fieldname</th>
                <th>Type</th>
                <th>Length</th>
                <th>Precision</th>
                <th>Origin</th>
                <th>flagfield</th>
            </tr>
            <!-- Here I used a '.' to simply keep the for-each-loop - it can be omitted, of course -->
            <xsl:for-each select=".">
                <tr>
                    <td>
                        <xsl:value-of select="Fieldname" />
                    </td>
                    <td>
                        <xsl:value-of select="Type" />
                    </td>
                    <td>
                        <xsl:value-of select="Length" />
                    </td>
                    <td>
                        <xsl:value-of select="Precision" />
                    </td>
                    <td>
                        <xsl:value-of select="Origin" />
                    </td>
                    <td>
                        <xsl:value-of select="flagfield" />
                    </td>
                </tr>
            </xsl:for-each>
        </table>
    </xsl:template>

</xsl:stylesheet>

The output looks like this:

enter image description here

Upvotes: 1

Related Questions