HTML XML Table with XSLT

I need to be able to turn flat xml datasets into html tables, and it's hard for me to find syntax examples that will suit my needs. I would like to use one style sheet that can convert similar search arrays into html tables with variable columns. This means that it cannot use the names of hard-coded elements except β€œstrings” and β€œstrings”.

The stylesheet that I will be able to convert:

<?xml version="1.0" encoding="UTF-8"?> <rows> <row> <AccountId>BlPUAA0</AccountId> <AccountName>Initech</AccountName> <AcocuntStatus>Client</AcocuntStatus> </row> <row> <AccountId>CJxIAAW</AccountId> <AccountName>Intertrode</AccountName> <AcocuntStatus>Prospect</AcocuntStatus> </row> </rows> 

in

 <table> <tr> <th>AccountId</th> <th>AccountName</th> <th>AcocuntStatus</th> </tr> <tr> <td>BlPUAA0</td> <td>Initech</td> <td>Client</td> </tr> <tr> <td>CJxIAAW</td> <td>Intertrode</td> <td>Client</td> </tr> </table> 

and this:

 <?xml version="1.0" encoding="UTF-8"?> <rows> <row> <AccountId>BlPUAA0</AccountId> <AccountName>Initech</AccountName> </row> <row> <AccountId>CJxIAAW</AccountId> <AccountName>Intertrode</AccountName> </row> </rows> 

in it:

 <table> <tr> <th>AccountId</th> <th>AccountName</th> </tr> <tr> <td>BlPUAA0</td> <td>Initech</td> </tr> <tr> <td>CJxIAAW</td> <td>Intertrode</td> </tr> </table> 
+4
source share
4 answers

I had a desire to try to solve this shortly after posting the question, and this is what I came up with. I think it makes you wait 24 hours before you can answer yourself.

 <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> <xsl:template match="/"> <table> <tr> <xsl:for-each select="rows/row[1]/*"> <th> <xsl:value-of select ="local-name()"/> </th> </xsl:for-each> </tr> <xsl:for-each select="rows/row"> <tr> <xsl:for-each select="*"> <td> <xsl:value-of select="."/> </td> </xsl:for-each> </tr> </xsl:for-each> </table> </xsl:template> </xsl:stylesheet> 
+4
source

Direct and short solution :

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:template match="/*"> <table><xsl:apply-templates select="row"/></table> </xsl:template> <xsl:template match="row[1]"> <tr><xsl:apply-templates select="*" mode="header"/></tr> <xsl:call-template name="standardRow"/> </xsl:template> <xsl:template match="row" name="standardRow"> <tr><xsl:apply-templates select="*"/></tr> </xsl:template> <xsl:template match="row/*"> <td><xsl:apply-templates select="node()"/></td> </xsl:template> <xsl:template match="row/*" mode="header"> <th><xsl:value-of select="name()"/></th> </xsl:template> </xsl:stylesheet> 

when applied to the first XML document provided :

 <rows> <row> <AccountId>BlPUAA0</AccountId> <AccountName>Initech</AccountName> <AcocuntStatus>Client</AcocuntStatus> </row> <row> <AccountId>CJxIAAW</AccountId> <AccountName>Intertrode</AccountName> <AcocuntStatus>Prospect</AcocuntStatus> </row> </rows> 

the desired, correct result is output:

 <table> <tr> <th>AccountId</th> <th>AccountName</th> <th>AcocuntStatus</th> </tr> <tr> <td>BlPUAA0</td> <td>Initech</td> <td>Client</td> </tr> <tr> <td>CJxIAAW</td> <td>Intertrode</td> <td>Prospect</td> </tr> </table> 

when applied to the second XML document provided:

 <rows> <row> <AccountId>BlPUAA0</AccountId> <AccountName>Initech</AccountName> </row> <row> <AccountId>CJxIAAW</AccountId> <AccountName>Intertrode</AccountName> </row> </rows> 

again the desired, correct result is obtained:

 <table> <tr> <th>AccountId</th> <th>AccountName</th> </tr> <tr> <td>BlPUAA0</td> <td>Initech</td> </tr> <tr> <td>CJxIAAW</td> <td>Intertrode</td> </tr> </table> 
+6
source

This style sheet:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <table> <xsl:apply-templates select="rows/row[1]" /> </table> </xsl:template> <xsl:template match="row"> <tr> <xsl:apply-templates mode="th" /> </tr> <xsl:apply-templates select="../row" mode="td" /> </xsl:template> <xsl:template match="row/*" mode="th"> <th> <xsl:value-of select="local-name()" /> </th> </xsl:template> <xsl:template match="row" mode="td"> <tr> <xsl:apply-templates /> </tr> </xsl:template> <xsl:template match="row/*"> <td> <xsl:apply-templates /> </td> </xsl:template> </xsl:stylesheet> 

It applies to:

 <rows> <row> <AccountId>BlPUAA0</AccountId> <AccountName>Initech</AccountName> <AcocuntStatus>Client</AcocuntStatus> </row> <row> <AccountId>CJxIAAW</AccountId> <AccountName>Intertrode</AccountName> <AcocuntStatus>Prospect</AcocuntStatus> </row> </rows> 

It produces:

 <table> <tr> <th>AccountId</th> <th>AccountName</th> <th>AcocuntStatus</th> </tr> <tr> <td>BlPUAA0</td> <td>Initech</td> <td>Client</td> </tr> <tr> <td>CJxIAAW</td> <td>Intertrode</td> <td>Prospect</td> </tr> </table> 

And applies to:

 <rows> <row> <AccountId>BlPUAA0</AccountId> <AccountName>Initech</AccountName> </row> <row> <AccountId>CJxIAAW</AccountId> <AccountName>Intertrode</AccountName> </row> </rows> 

It produces:

 <table> <tr> <th>AccountId</th> <th>AccountName</th> </tr> <tr> <td>BlPUAA0</td> <td>Initech</td> </tr> <tr> <td>CJxIAAW</td> <td>Intertrode</td> </tr> </table> 

As an alternative, this stylesheet displays the same result using a conditional and one smaller template:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <table> <xsl:apply-templates select="rows/row" /> </table> </xsl:template> <xsl:template match="row"> <xsl:if test="position()=1"> <tr> <xsl:apply-templates mode="th" /> </tr> </xsl:if> <tr> <xsl:apply-templates /> </tr> </xsl:template> <xsl:template match="row/*" mode="th"> <th> <xsl:value-of select="local-name()" /> </th> </xsl:template> <xsl:template match="row/*"> <td> <xsl:apply-templates /> </td> </xsl:template> </xsl:stylesheet> 
+2
source

A few days ago I publish an article, I hope that it will help you: http://web.swfideas.com/?p=12191

Based on this data:

 <?xml version="1.0" encoding="UTF-8"?> <!-- Edited by XMLSpy --> <table-node> <tbody> <tr> <td>[C1R1]</td> <td>[C2R1]</td> </tr> <tr> <td>[C1R2]</td> <td>[C2R2]</td> </tr> <tr> <td>[C1R3]</td> <td>[C2R3]</td> </tr> </tbody> </table-node> 

Now the kernel, our XSLT template:

 <?xml version="1.0" encoding="ISO-8859-1"?> <!-- Coded by SWFideas --> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- table template --> <xsl:template match="table-node"> <table style="border:solid #000000 1px;border-spacing: 0;border-collapse: collapse;"> <xsl:for-each select="tbody"> <tbody> <xsl:for-each select="tr"> <tr> <xsl:for-each select="td"> <td style="border:solid #000000 1px; padding: 5px;"> <xsl:value-of select="."/> </td> </xsl:for-each> </tr> </xsl:for-each> </tbody> </xsl:for-each> <table> </xsl:template> </xsl:stylesheet> 

In this first approach, I avoid using COLSPAN and other real properties (implementation soon, I promise). Thus, the result of applying XSLT would be:

 <table style="border:solid #000000 1px;border-spacing: 0;border-collapse: collapse;"> <tbody> <tr> <td style="border:solid #000000 1px; padding: 5px;">[C1R1]</td> <td style="border:solid #000000 1px; padding: 5px;">[C2R1]</td> </tr> <tr> <td style="border:solid #000000 1px; padding: 5px;">[C1R2]</td> <td style="border:solid #000000 1px; padding: 5px;">[C2R2]</td> </tr> <tr> <td style="border:solid #000000 1px; padding: 5px;">[C1R3]</td> <td style="border:solid #000000 1px; padding: 5px;">[C2R3]</td> </tr> </tbody> </table> 

You can try it here: http://www.xsltcake.com/slices/gNfh6i/2

0
source

Source: https://habr.com/ru/post/1348018/


All Articles