Search code examples
htmlxmlxsltxslt-2.0

Need to create the HTML table from XML Attribute


I'm having the Input XML with attribute values, need to create the HTML Table using the XSLT.

Input XML:

<manuals>
    <title>Test</title>
    <results>
        <auto name="Data">
            <manual name="Blank">
                <result column="Data"/>
            </manual>
        </auto>
        <auto name="View">
            <manual name="Blank2">
                <result column="Information"/>    
                <result column="Test"/>
            </manual>
            <manual name="Value">
                <result column="Exceptions"/>
            </manual>
        </auto>
    </results>
</manuals>

Expected HTML:

<!DOCTYPE HTML>
<html lang="en">
   <head>
      <title>XXX</title>
      <style>
         table,th, td{border: 1px solid black; padding: 5px;}
      </style>
   </head>
   <body>
      <table>
         <caption>Test</caption>
         <tr>
            <td colspan="2" style="text-align:center">Data</td>
         </tr>
         <tr>
            <td>Blank</td>
            <td>Data</td>
         </tr>
         <tr>
            <td colspan="2" style="text-align:center">View</td>
         </tr>
         <tr>
            <td>Blank2</td>
            <td>
               <ul>
                  <li>Information</li>
                  <li>Test</li>
            </ul>
            </td>
         </tr>
         <tr>
            <td>Value</td>
            <td>Exceptions</td>
         </tr>
         </table>
   </body>
</html>

XSL I have tried is:

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

    <xsl:output method="html" indent="yes" version="5.0"/>

    <xsl:template match="/">
        <html lang="en">
            <head>
                <title>test</title>
                <style>
                    table,th, td{border: 1px solid black; padding: 5px;}
                </style>
            </head>
            <body>
         <table>
             <caption><xsl:value-of select="title"/></caption>
             <xsl:for-each select="auto">
                 <tr>
                     <td colspan="2" style="text-align:center"><xsl:value-of select="@name"/></td>
                     </tr>
             </xsl:for-each>
             <xsl:for-each select="manual">
                 <tr>
                     <td><xsl:value-of select="@name"/></td>
                 </tr>
             </xsl:for-each>
        </table>
            </body>
        </html>
    </xsl:template>

</xsl:stylesheet>

But I can't able to get my expected results. In that Input there is having two results in the manual, that would needs to comes under the unordered list. I'm using XSLT 1.0, please suggest any new version


Solution

  • When you want to select nodes in your XSLT program, you have to give an absolute or relative path to that node. For example, when you execute <xsl:template match="/"> and inside of that template, you want to select the tag <title>, you have to give the relative path to it, as in <xsl:value-of select="manuals/title">, or the absolute path as in <xsl:value-of select="/manuals/title"> or <xsl:value-of select="//title"> and not simply <xsl:value-of select="title">.

    I also had to guess how to produce the unordered lists with <ul>...</ul> since it was not foreseen in your code.

    Try this XSLT code:

    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
      <xsl:output method="html" indent="yes" version="5.0"/>
      <xsl:template match="/">
        <html lang="en">
          <head>
            <title>test</title>
            <style>table,th, td {border: 1px solid black; padding: 5px;}</style>
          </head>
          <body>
            <table>
              <caption>
                <xsl:value-of select="manuals/title"/>
              </caption>
              <xsl:for-each select="manuals/results/auto">
                <tr>
                  <td colspan="2" style="text-align:center">
                    <xsl:value-of select="@name"/>
                  </td>
                </tr>
                <xsl:for-each select="manual">
                  <tr>
                    <td>
                      <xsl:value-of select="@name"/>
                    </td>
                    <td>
                      <xsl:choose>
                        <xsl:when test="count (result/@column) = 0">
                          (empty)<!-- you can decide to do something else here -->
                        </xsl:when>
                        <xsl:when test="count (result/@column) = 1">
                          <xsl:value-of select="result/@column"/>
                        </xsl:when>
                        <xsl:otherwise>
                          <ul>
                            <xsl:for-each select="result/@column">
                              <li>
                                <xsl:value-of select="."/>
                             </li>
                            </xsl:for-each>
                          </ul>
                        </xsl:otherwise>
                      </xsl:choose>
                    </td>
                  </tr>
                </xsl:for-each>
              </xsl:for-each>
            </table>
          </body>
        </html>
      </xsl:template>
    </xsl:stylesheet>
    

    Below, the output I get with xsltproc, without indentation I don't kow why:

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
    <html lang="en">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>test</title>
    <style>table,th, td {border: 1px solid black; padding: 5px;}</style>
    </head>
    <body><table>
    <caption>Test</caption>
    <tr><td colspan="2" style="text-align:center">Data</td></tr>
    <tr>
    <td>Blank</td>
    <td>Data</td>
    </tr>
    <tr><td colspan="2" style="text-align:center">View</td></tr>
    <tr>
    <td>Blank2</td>
    <td><ul>
    <li>Information</li>
    <li>Test</li>
    </ul></td>
    </tr>
    <tr>
    <td>Value</td>
    <td>Exceptions</td>
    </tr>
    </table></body>
    </html>