Skip to main content
Email Password   helpLost your password?

Introduction

Sometimes you need to create dynamic pages. You may allow users to build their own applications by selecting the fields they need. In this article, I will show how to build dynamic applications by using ASP.NET and XML. In this example, I use XML for meta-programming or generative programming. I use XML with an XSLT to generate ASP.NET PRE, utilizing intrinsic ASP.NET parsing methods with the XSLT output. Steps that we need to do:

First, what we need to come up with is a good structure of our page in a XML file. A basic page structure is defined below. The example structure consists of field elements, with attributes, properties and listitems.

<FORM>
  <PAGES>
    <PAGE title="Page Title" id="page_1">
      <FIELDS>
        
    <!-- create regular TextBox -->
    <FIELD type="TextBox" label="Last Name:" required="true">
          <PROPERTIES>
            <PROPERTY name="ID">LAST_NAME</PROPERTY>
          </PROPERTIES>
        </FIELD>

    <!-- create multiline TextBox (textarea) -->
        <FIELD type="TextBox" label="Description:">
          <PROPERTIES>
            <PROPERTY name="ID">DESCRIPTION</PROPERTY>
            <PROPERTY name="TextMode">MultiLine</PROPERTY>
            <PROPERTY name="Cols">30</PROPERTY>
            <PROPERTY name="Rows">2</PROPERTY>
          </PROPERTIES>
        </FIELD>

    <!-- regular textbox prefilled with text -->
    <FIELD type="TextBox" label="Prefilled Contrl:">
          <PROPERTIES>
            <PROPERTY name="ID">PREFILLED_CONTROL</PROPERTY>
            <PROPERTY name="Text">Some Text</PROPERTY>
          </PROPERTIES>
        </FIELD>

        <!-- regular text box which must filled 
                                 and allowed Date datata type -->
        <FIELD type="TextBox" label="Start Date:" 
                      required="true" validation="Date">
          <PROPERTIES>
            <PROPERTY name="ID">START_DATE</PROPERTY>
          </PROPERTIES>
        </FIELD>

    <!-- create select box -->
        <FIELD type="DropDownList" label="Title:">
          <PROPERTIES>
            <PROPERTY name="ID">TITLE</PROPERTY>
          </PROPERTIES>
          <LISTITEMS>
            <LISTITEM value="">Select One</LISTITEM>
            <LISTITEM value="1">Architector</LISTITEM>
            <LISTITEM value="2">Sr. Developer</LISTITEM>
            <LISTITEM value="3">Programmer</LISTITEM>
            <LISTITEM value="4">Web Designer</LISTITEM>
          </LISTITEMS>
        </FIELD>

    <!-- radio buttons list -->    
        <FIELD type="RadioButtonList" label="Are you US citizen?">
          <PROPERTIES>
            <PROPERTY name="ID">IS_US_CITIZEN</PROPERTY>
            <PROPERTY name="RepeatColumns">1</PROPERTY>
            <PROPERTY name="RepeatDirection">Vertical</PROPERTY>
            <PROPERTY name="RepeatLayout">Table</PROPERTY>
            <PROPERTY name="TextAlign">Right</PROPERTY>
          </PROPERTIES>
          <LISTITEMS>
            <LISTITEM value="1">Yes</LISTITEM>
            <LISTITEM value="0">No</LISTITEM>
          </LISTITEMS>
        </FIELD>

    <!-- check box list -->
        <FIELD type="CheckBoxList" label="Languages:">
          <PROPERTIES>
            <PROPERTY name="ID">LANGUAGES</PROPERTY>
            <PROPERTY name="RepeatColumns">1</PROPERTY>
            <PROPERTY name="RepeatDirection">Vertical</PROPERTY>
            <PROPERTY name="RepeatLayout">Table</PROPERTY>
            <PROPERTY name="TextAlign">Right</PROPERTY>
          </PROPERTIES>
          <LISTITEMS>
            <LISTITEM value="C#">C#</LISTITEM>
            <LISTITEM value="Java">Java</LISTITEM>
            <LISTITEM value="VB">Visual Basic</LISTITEM>
          </LISTITEMS>
        </FIELD>

    <!-- here is a hyperlink (a) -->
        <FIELD type="HyperLink">
          <PROPERTIES>
            <PROPERTY name="ID">LINK</PROPERTY>
            <PROPERTY name="NavigateUrl">javascript:void(alert('Hello ooo'));
            </PROPERTY>
            <PROPERTY name="Text">Say Hello</PROPERTY>
          </PROPERTIES>
        </FIELD>

    <FIELD type="html" src="file path"/>

    <!-- you can place here any other asp controls -->

      </FIELDS>
    </PAGE>
    
    ...

  </PAGES>
</FORM>

Next step is to create XSLT style to transform our XML schema The XSLT iterates through each field, first outputting a label for the field as plain text. The stylesheet also checks if the field is required, and adds a RequiredFieldValidator if needed. The stylesheet then creates a Web Control (it could be any valid web control such as TextBox, RadioButtonList, DropDownList, etc.). ListItems are created for each of the ListControls.

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:asp="remove">
  <xsl:output method="xml" indent="yes" encoding="utf-8" omit-xml-declaration="yes">
  </xsl:output>
  <xsl:template match="/">

   <!-- page id parameter if we have more than 1 page in our XML file -->
   <xsl:param name="pageid"/>

     <!-- start form page -->
     <table cellpadding="0" cellspacing="5">

       <!-- set title of the current page -->
       <tr>
        <td colspan="3" align="center" style="font-size:25px">
         <xsl:value-of select="FORM/PAGES/PAGE[@id=$pageid]/@title" />
        </td>
       </tr>
       <tr><td colspan="3" style="height:20px"></td></tr>

       <!-- iterate through page fields -->
       <xsl:for-each select="FORM/PAGES/PAGE[@id=$pageid]/FIELDS/FIELD">

       <!-- create row -->
       <xsl:element name="tr">
        <xsl:attribute name="id">
          TR_<xsl:value-of select="PROPERTIES/PROPERTY[@name='ID']"></xsl:value-of>
        </xsl:attribute>

        <!-- hide the row -->
        <xsl:if test="@display='none'">
         <xsl:attribute name="style">display:none;</xsl:attribute>
        </xsl:if>

        <xsl:choose>

         <!-- this is the way to place "include" files into your PRE -->
         <xsl:when test="@type='HTML'">
          <td colspan="3">
            <!-- #include file="<xsl:value-of select="@src"></xsl:value-of>" -->
          </td>
         </xsl:when>

         <!-- other controls -->
         <xsl:otherwise>

         <!-- field label column -->
         <td valign="top">
          <xsl:value-of select="@label" />
         </td>

         <!-- field column -->
         <td>

          <!-- field element -->
          <xsl:element name="asp:{@type}">
           <xsl:attribute name="runat">server</xsl:attribute>
           <xsl:for-each select="./PROPERTIES/PROPERTY">
             <xsl:attribute name="{@name}">
               <xsl:value-of select="current()"></xsl:value-of>
             </xsl:attribute>
           </xsl:for-each>
           <xsl:for-each select="./LISTITEMS/LISTITEM">
            <asp:ListItem value="{@value}">
              <xsl:value-of select="current()"></xsl:value-of>
            </asp:ListItem>
           </xsl:for-each>
          </xsl:element>
         </td>

         <!-- validation message column -->
         <td>
          <xsl:if test="@required='true'">
           <asp:RequiredFieldValidator ErrorMessage="Required" runat="server" 
                 ControlToValidate="{PROPERTIES/PROPERTY[@name='ID']}" />
          </xsl:if>

          <xsl:if test="@validation='Date'">
           <asp:CompareValidator ErrorMessage="Dates Only" runat="server" 
                Operator="DataTypeCheck" Type="Date" 
                ControlToValidate="{PROPERTIES/PROPERTY[@name='ID']}" />
          </xsl:if>

          <xsl:if test="@validation='Number'"> 
           <asp:CompareValidator ErrorMessage="Numbers Only" runat="server" 
               Operator="DataTypeCheck" Type="Integer" 
               ControlToValidate="{PROPERTIES/PROPERTY[@name='ID']}" />
          </xsl:if>

          <xsl:if test="@validation='Currency'">
           <asp:CompareValidator ErrorMessage="Currency Only" runat="server" 
               Operator="DataTypeCheck" Type="Currency" 
               ControlToValidate="{PROPERTIES/PROPERTY[@name='ID']}" />
          </xsl:if>
         </td>
        </xsl:otherwise>

       </xsl:choose>
      </xsl:element>

      </xsl:for-each>
     </table>
  </xsl:template>
</xsl:stylesheet>

Our XSLT file has a prefix (xmlns:asp="remove") defined for the XSL namespace. This is used to generate plain HTML. Now we are ready to write our Page transformer.

    ...
    private readonly string XslFile = @"...\default.xslt";
    private readonly string XmlFile = @"...\default.config";

    ...
    private void Page_Load(object sender, System.EventArgs e)
    {
        string pageId = "page_1";

        if (!Page.IsPostBack)
        {

            /**
             * Transform aspx page with fields from xml file
             * Get transform result as a string
             * Parse controls into a parent control holder
             */

            XmlDocument xdoc = new XmlDocument();
            xdoc.Load(XmlFile);

            // load xslt to do transformation

            XslTransform xsl = new XslTransform();
            xsl.Load(XslFile);

            // load xslt arguments to load specific page from xml file

            // this can be used if you have multiple pages

            // in your xml file and you loading them one at a time

            XsltArgumentList xslarg = new XsltArgumentList();
            xslarg.AddParam("pageid", "", pageId);

            // get transformed results

            StringWriter sw = new StringWriter();
            xsl.Transform(xdoc, xslarg, sw);
            string result = sw.ToString().Replace("xmlns:asp=\"remove\"", 
                     "").Replace("&lt;","<").Replace("&gt;",">");
            // free up the memory of objects that are not used anymore

            sw.Close();

            // parse the controls and add it to the page

            Control ctrl = Page.ParseControl(result);
            Page.Controls.Add(ctrl);
        }
    }

    private void BtnSave_Click(object sender, System.EventArgs e)
    {
        // save data into a data container

        // ...

        Response.Write (Request.Form["LAST_NAME"]);
    }

Conclusion

In this article, we separate data from content to make a cleaner design and for better maintainability. When XML is combined with XSLT, ASP.NET server controls become even more powerful. This opens up numerous possibilities for dynamic and robust systems.

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralWTMI Please Pin
George.Saraiva
4:42 21 Jul '09  
GeneralNeeed working version for asp.net 2.0 Pin
ch.ramesh
5:45 19 May '09  
GeneralWTMI Pin
APTL
8:43 18 Feb '09  
GeneralWTMI.Util Pin
Member 3970593
1:17 16 Jan '09  
GeneralReflectionManager Pin
Member 3970593
0:51 16 Jan '09  
GeneralEvent handle in XSLT file Pin
phuongduy2010
5:34 11 Nov '08  
GeneralOk Why Some Control is visible? Pin
phuongduy2010
6:40 7 Nov '08  
GeneralCan I use HTML Tags in the .config file Pin
Prakash Koshti
1:55 30 Sep '08  
Generalcode for WTMI.Collections needed [modified] Pin
the bill
11:05 25 Sep '08  
GeneralDeveloping a dynamic website using XML, XSL, C# and SQL Server Pin
Member 984388
10:07 4 Aug '08  
QuestionProblem with the output of this project Pin
Will_FLBK
23:40 29 Jun '08  
GeneralNeeed working version for asp.net 2.0 Pin
krishnakonline
4:45 18 Jun '08  
GeneralHandling Events & Displaying data from database Pin
Anne_mathew
22:06 12 Nov '07  
QuestionEvent Handling Pin
pawan venugopal
0:44 29 Aug '07  
GeneralHey all, I figured how to get events to fire Pin
thisisavalidusername
5:33 25 Jul '07  
AnswerRe: Hey all, I figured how to get events to fire Pin
Kr0d
17:48 24 Sep '08  
QuestionHandling Events Pin
n8shadow
8:06 13 Jul '07  
Generalnot able to run.. Pin
vijaysaxena
1:49 2 Jul '07  
GeneralThe XSLT code has little error. Pin
V'ru
19:26 29 Apr '07  
GeneralParameter value not getting Pin
V'ru
3:55 26 Apr '07  
AnswerRe: Parameter value not getting Pin
KNet1
0:44 3 May '07  
GeneralVB Code Pin
shafiqm2
6:54 23 Apr '07  
GeneralGenerating Dynamic aspx pages Pin
Kherva
8:45 5 Jan '07  
QuestionAny Working copy for dotNet 2.0 ? Pin
SandeepNahta
17:20 22 Nov '06  
Generalsome files missing Pin
Vhakti
11:13 9 Aug '06  


Last Updated 15 Oct 2004 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2009