XSLT : Using reusable XSL to generate HTML Form dynamically

In this article , am going to describe how to generate html form dynamically using reusable xsl file.


Problem Statement :

Suppose I have large number of xml files :  There is one condition that : there won't be any more nested tags . But the name of property tag will be different for each xmldata file.
First xml:
<xmldata1>
    <record>
        <property11>abc</property11>
        <property12>def</property12>
        <property13>xyz</property13>
        ............
    </record>
    ........</xmldata1>
Second xml:
<xmldata2>
    <record>
        <property21>abc</property21>
        <property22>def</property22>
        <property23>xyz</property23>
        ............
    </record>
    ........</xmldata2>
and so on.
So i want to dynamically generate a HTML Form using XSLT  that could be reused to for any such xml . Where a simple text box should be used to read each property. and we can take the first record as reference for number and name of properties.



Desired output (for each xmldatas)

<form name ="xmldata1">
    <table>
        <tr>
            <td>property11 :</td>
            <td><input type="text" name="property11"></td>
        </tr>
        .......
        and so on
    </table>
</form>


XSL for generating dynamic HTML :


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

    <!--Template match for the document element, no matter what the name -->
    <xsl:template match="/*">
<html>
<body>
<h3>Enter the Details</h3>
      <form name="{local-name()}">
        <table>
           <!--Apply-templates for all of the record/property elements -->
           <xsl:apply-templates select="*/*"/>
         </table>
      </form>
</body>
</html>
    </xsl:template>

    <!--Match on all of the property elements and create a new row for each -->
    <xsl:template match="/*/*/*">
      <tr>
        <td><xsl:value-of select="local-name()"/> :</td>
        <td><input type="text" name="{local-name()}"/></td>
      </tr>
    </xsl:template>

</xsl:stylesheet>

Testing :
XmlData File :
<users>
    <user>
        <UserName></UserName>
        <FirstName></FirstName>
        <LastName></LastName>
        <Address></Address>
        <Job></Job>
    </user>
</users> 


XSLT Transformer Java Code :
The transformation can be achieved by the java class described in this article.

The output of Transformation  :
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
  <head>
  </head>
  <body>
    <h3>
      Enter the Details
    </h3>
    <form name="users" id="users">
      <table>
        <tr>
          <td>
            UserName :
          </td>
          <td>
            <input type="text" name="UserName">
          </td>
        </tr>
        <tr>
          <td>
            FirstName :
          </td>
          <td>
            <input type="text" name="FirstName">
          </td>
        </tr>
        <tr>
          <td>
            LastName :
          </td>
          <td>
            <input type="text" name="LastName">
          </td>
        </tr>
        <tr>
          <td>
            Address :
          </td>
          <td>
            <input type="text" name="Address">
          </td>
        </tr>
        <tr>
          <td>
            Job :
          </td>
          <td>
            <input type="text" name="Job">
          </td>
        </tr>
      </table>
    </form>
  </body>
</html>

Html Output view :

Enter the Details

UserName :
FirstName :
LastName :
Address :
Job :
Advantage of doing all this : this reduces the effort of generating multiple HTML form by other means. This is simple and doesnot required other tools.


I had asked this question in stackoverflow


1 comment :

  1. wow! I didn't know xslt can be used in such a way. You just solved my problem on parsing xml file and have the output displayed as if it is new xml file.

    thanks and i hope you continue sharing!

    ReplyDelete

Your Comment and Question will help to make this blog better...