-1

I have a SQL query that produces results with 7 columns and several rows of data.

I convert this into XML and run it through XSLT to produce HTML and everything works fine. XSLT output looks like this:

                  Header info

Row 1: 1 | 2 | 3 | 4 | 5 | 6 | 7 |

Row 2: 1 | 2 | 3 | 4 | 5 | 6 | 7 |

But now the data in some of the columns takes up a lot of room and I now need to stack the columns in XSLT to produce results like this:

1 | 2 | 3 |

4 | 5 | 6 |

7

I'd like column 4 to go under column 1 and 7 to span across the 3 columns above it.

here is a much simplified version of my XML:

<XML_Data>
  <Row>
    <EMP_ID>APf92C56</EMP_ID>
    <ID>129190950</ID>
    <KEY>H59460973</KEY>
    <COMP_TS>2015-01-26 11:31</COMP_TS>
    <CODE>500</CODE>
    <REASON>Text String</REASON>
    <CREATE_Reason>Very long text string</CREATE_Reason>
  </Row>
  <Row>
      <EMP_ID>APf92C56</EMP_ID>
      <ID>129190950</ID>
      <KEY>H59460973</KEY>
      <COMP_TS>2015-01-26 11:31</COMP_TS>
      <CODE>500</CODE>
      <REASON>Text String</REASON>
      <CREATE_Reason>Very long text string</CREATE_Reason>
  </Row>

</XML_Data>

Here is my current XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:template match="/ROOT">
        <table border="0" cellpadding="6">
          <tr>
            <td style="font-weight:bold;">EMP_ID</td>
            <td style="font-weight:bold;">ID</td>
            <td style="font-weight:bold;">KEY</td>
            <td style="font-weight:bold;">COMP_TS</td>
            <td style="font-weight:bold;">CODE</td>
            <td style="font-weight:bold;">REASON</td>
            <td style="font-weight:bold;">CREATE_Reason</td>
          </tr>

           <xsl:for-each select="XML_Data/Row">
            <tr>
              <xsl:for-each select="./*">
                <td>
                  <xsl:value-of select="." disable-output-escaping="yes" />
                </td>
              </xsl:for-each>
            </tr>
          </xsl:for-each>
        </table>
  </xsl:template>
</xsl:stylesheet>

I read this response: XSL xsl:template match="/" and played around with <xsl:template match="element"> but without knowing how to force a column onto a new line I didn't get very far.

I know SO is not a code generation tool, but I've combed through books and online and cant find what I'm looking for. Any help, even if its just a push in the right direction, would be most appreciated.

Community
  • 1
  • 1
min222002
  • 21
  • 6
  • Could you post the expected output of your example **as code**? – michael.hor257k Jan 28 '15 at 14:19
  • Note also that `<1>` is not a valid element name, so your given input cannot be processed at all. – michael.hor257k Jan 28 '15 at 14:23
  • Thank you for the response. I know they aren't valid, I just wanted to give a quick representation. I wanted to focus on the XSL and how to grab an element and put it on a new line. – min222002 Jan 28 '15 at 14:42
  • 1
    But then we cannot give you a precise answer. We need well-formed, accurate input XML - and the output you expect, also in XML, not as a description. Thanks! – Mathias Müller Jan 28 '15 at 14:44
  • I've updated the XML to better represent the data it contains and my needs. Thank you. – min222002 Jan 28 '15 at 15:06
  • I don't see that your needs are better represented. In particular I am puzzled by what headers you expect your table to have, when each column combines data from two or three different fields. – michael.hor257k Jan 28 '15 at 15:12
  • Sorry for the confusion. I don't even care about the headers, we can remove them. What I need to do is put the COMP_TS element on a new row and put the CREATE_Reason element on a new row that spans across the ones above it. If it matters, this is going out in an email with HTML and space is a premium. Even if the answer is a hack, but works, at this point I'll take it because nothing else I've tried works. – min222002 Jan 28 '15 at 15:19

2 Answers2

0

I don't even care about the headers, we can remove them. What I need to do is put the COMP_TS element on a new row and put the CREATE_Reason element on a new row that spans across the ones above it.

If you don't care about the headers, nor about separating the records, try simply:

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="/XML_Data">
    <table border="1">
        <xsl:for-each select="Row">
            <tr>
                <td><xsl:value-of select="EMP_ID"/></td>
                <td><xsl:value-of select="ID"/></td>
                <td><xsl:value-of select="KEY"/></td>
            </tr>
            <tr>
                <td><xsl:value-of select="COMP_TS"/></td>
                <td><xsl:value-of select="CODE"/></td>
                <td><xsl:value-of select="REASON"/></td>
            </tr>
            <tr>
                <td colspan="3"><xsl:value-of select="CREATE_Reason"/></td>
            </tr>
        </xsl:for-each>
    </table>
</xsl:template>

</xsl:stylesheet>

The (rendered) result when applied to your example input:

enter image description here

michael.hor257k
  • 113,275
  • 6
  • 33
  • 51
-1

Based on your information, a basic solution may be:

<table cellspacing="0" width="100%" cellpadding="0">
    <tr>
        <xsl:for-each select="//XML_Data/Row" >
            <td>
                <xsl:value-of select="current()/1"/>
            </td>
            <td>
                <xsl:value-of select="current()/2"/>
            </td>
            <td>
                <xsl:value-of select="current()/3"/>
            </td>
        </xsl:for-each>
    </tr>
    <tr>
        <xsl:for-each select="//XML_Data/Row" >
            <td>
                <xsl:value-of select="current()/4"/>
            </td>
            <td>
                <xsl:value-of select="current()/5"/>
            </td>
            <td>
                <xsl:value-of select="current()/6"/>
            </td>
        </xsl:for-each>
    </tr>
    <tr>
        <xsl:for-each select="//XML_Data/Row" >
            <td colspan="3">
                <xsl:value-of select="current()/7"/>
            </td>   
        </xsl:for-each>
    </tr>
</table>            
lcryder
  • 486
  • 2
  • 8