Creating a Clean Data Entry Form
When you build a web interface that accepts user input, the first thing you notice is how cluttered the code can become if you mix markup and script haphazardly. A disciplined approach starts with separating the visual layer from the logic layer. In the ASP example below the form that collects a person’s name, age, gender, and postal code lives in a standalone section of the page. The rest of the page contains only ASP code that processes the form once it is submitted. The HTML portion is intentionally minimal. A simple table layout keeps the fields aligned, and the controls are given clearname attributes because ASP will read those values from the request. Notice how the form uses the POST method: it keeps the data hidden from the URL, which is standard practice for submissions that create or modify server-side data.
Here is the form markup in full. You can copy it into a new file called VerifyPerson.asp and open it in a browser to see the layout. Replace the placeholder images with your own graphics if you like; the code below is all you need to capture the data.
<form action="VerifyPerson.asp" method="post" name="frmPerson" id="frmPerson"></p>
<p> <table></p>
<p>
<tr><td>Name:</td><td><input type="text" name="Name" id="Name"></td></tr></p>
<p>
<tr><td>Age:</td><td><input type="text" name="Age" id="Age"></td></tr></p>
<p>
<tr><td>Gender:</td><td></p>
<p>
<select name="Gender" id="Gender"></p>
<p>
<option value="Male">Male</option></p>
<p>
<option value="Female">Female</option></p>
<p>
</select></p>
<p>
</td></tr></p>
<p>
<tr><td>Postal Code:</td><td><input type="text" name="PostalCode" id="PostalCode"></td></tr></p>
<p>
<tr><td colspan="2" style="text-align:center"></p>
<p>
<input type="submit" value="Submit" name="submit"></p>
<p>
<input type="reset" value="Reset" name="reset"></p>
<p> </table></p>
<p></form></p>
div and style them with CSS; the logic stays exactly the same.
With the form in place, we can now talk about the processing side. We’ll keep all ASP code after the form so that the page first shows the form to the user. When the form is posted, the same page reloads and ASP runs the logic that follows. By keeping the code in the same file, we avoid an extra round trip to a different page, simplifying debugging and maintenance.
The separation of concerns is more than just a code organization trick. When you test the form locally, you see that the fields behave as expected: the browser enforces required fields, and the form data is posted to the server. In a real application you would add client‑side validation with JavaScript or HTML5 attributes, but for this example we rely on server‑side checks. The next section explains how the ASP script grabs those values and writes them to an XML file.
Before moving forward, make sure you have a blank XML file called Person.xml in the same directory. It will hold the list of people you add. The ASP code will load this file, add a new Person node, and then save it back. If the file doesn’t exist, you’ll need to create it manually with at least a root element like <PersonList></PersonList>. Once that file is ready, you’re set for the next part of the journey.
Processing Submissions and Persisting Data in XML
When the form posts back toVerifyPerson.asp, the ASP runtime starts executing the script at the top of the file. The first task is to detect whether the user actually clicked the submit button. ASP exposes the form values through the Request.Form collection, and we can check if the submit field exists. If it does, we continue with validation; otherwise, we simply display the form again.
Below is the skeleton of the check. We store the result in a variable named submitCount and wrap everything in a simple If statement. The code uses VBScript syntax, which is the default for classic ASP.
<p>Dim submitCount</p>
<p>submitCount = Request.Form("submit").Count</p>
<p>If submitCount > 0 Then</p>
<p>
' Process the data</p>
<p>Else</p>
<p>
' Just show the form</p>
<p>End If</p>
<p>%>
If branch we read each field into its own variable. The Request.Form collection automatically returns an empty string if the field is missing, so no extra error handling is needed at this point. Keep the names exactly as they appear in the name attributes; any mismatch will result in "" values.
Dim name, age, gender, postalCode</p>
<p>name = Request.Form("Name")</p>
<p>age = Request.Form("Age")</p>
<p>gender = Request.Form("Gender")</p>
<p>postalCode = Request.Form("PostalCode")</p>
Dim errorMsg</p>
<p>errorMsg = ""</p>
<p>If name = "" Then errorMsg = errorMsg & "Name "</p>
<p>If age = "" Then errorMsg = errorMsg & "Age "</p>
<p>If postalCode = "" Then errorMsg = errorMsg & "Postal Code "</p>
<p>If errorMsg
<p>
Response.Write "<p>Please enter the following data:<br><b>" & errorMsg </b></p>"</p>
<p>Else</p>
<p>
' All fields are present – proceed to save</p>
<p>End If</p>
Microsoft.FreeThreadedDOMDocument object, which lets you parse and manipulate XML. We set async="false" to keep the code synchronous; this makes error handling simpler and avoids race conditions. The load method takes the physical path of the file, which we obtain using Server.MapPath
Dim xmlDoc</p>
<p>Set xmlDoc = Server.CreateObject("Microsoft.FreeThreadedDOMDocument")</p>
<p>xmlDoc.async = False</p>
<p>xmlDoc.load Server.MapPath("Person.xml")</p>
After the document is loaded we need to locate the root node that will hold all Person entries. In this example the root is PersonList. We get a collection of matching nodes and use the first one as the parent for new entries. If the root node is missing, you would need to create it, but we assume it exists.
Dim nodeList, parentNode</p>
<p>Set nodeList = xmlDoc.getElementsByTagName("PersonList")</p>
<p>If nodeList.length > 0 Then</p>
<p>
Set parentNode = nodeList(0)</p>
<p>Else</p>
<p>
' Create the root if necessary</p>
<p>
Set parentNode = xmlDoc.createElement("PersonList")</p>
<p>
xmlDoc.appendChild parentNode</p>
<p>End If</p>
Now we build the new Person node and its child elements. Each piece of data from the form becomes a separate node, making the XML human-readable and easy to query later. The text property of a node stores the string value.
Dim personNode, nameNode, ageNode, genderNode, pcodeNode</p>
<p>Set personNode = xmlDoc.createElement("Person")</p>
<p>Set nameNode = xmlDoc.createElement("Name")</p>
<p>nameNode.text = name</p>
<p>Set ageNode = xmlDoc.createElement("Age")</p>
<p>ageNode.text = age</p>
<p>Set genderNode = xmlDoc.createElement("Gender")</p>
<p>genderNode.text = gender</p>
<p>Set pcodeNode = xmlDoc.createElement("PostalCode")</p>
<p>pcodeNode.text = postalCode</p>
Once the child nodes are ready, we assemble them by appending to the Person node. Finally, the complete Person node is appended to the root list.
personNode.appendChild nameNode</p>
<p>personNode.appendChild ageNode</p>
<p>personNode.appendChild genderNode</p>
<p>personNode.appendChild pcodeNode</p>
<p>parentNode.appendChild personNode</p>
The last step writes the updated document back to disk. The save method overwrites the original file, preserving all existing entries and adding the new one.
xmlDoc.save Server.MapPath("Person.xml")</p>
<p>%>
With this block of code in place, each time the form is submitted a new Person element appears in Person.xml. You can verify this by opening the XML file in a text editor or a browser. The file will look like this after a few submissions:
<PersonList></p>
<p> <Person></p>
<p>
<Name>Alice</Name></p>
<p>
<Age>30</Age></p>
<p>
<Gender>Female</Gender></p>
<p>
<PostalCode>12345</PostalCode></p>
<p> </Person></p>
<p> <Person></p>
<p>
<Name>Bob</Name></p>
<p>
<Age>25</Age></p>
<p>
<Gender>Male</Gender></p>
<p>
<PostalCode>67890</PostalCode></p>
<p> </Person></p>
<p></PersonList></p>
You now have a reliable server‑side routine that captures user input and stores it in a structured XML file. The next logical step is to present that data back to the user in a readable table. Classic ASP and XSL can do that elegantly.
Rendering Stored Data with XSL Transformation
The XML file you just populated holds all the person records. To display them, you’ll need a transformation stylesheet that turns the XML into HTML. XSLT is designed for this exact purpose, and classic ASP can load both the XML and the XSL files, then apply the transformation on the server before sending the result to the client.
First, create a file called person.xsl in the same folder. This stylesheet defines a template that matches the root element and iterates over each Person child. The example below uses a simple table layout: the header row lists the column names, and each subsequent row displays one person’s details.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"></p>
<p> <xsl:output method="html" indent="yes" encoding="UTF-8"/></p>
<p> <xsl:template match="/PersonList"></p>
<p>
<table border="1" cellpadding="4" cellspacing="0"></p>
<p>
<tr></p>
<p>
<th>Name</th></p>
<p>
<th>Age</th></p>
<p>
<th>Gender</th></p>
<p>
<th>Postal Code</th></p>
<p>
</tr></p>
<p>
<xsl:apply-templates select="Person"/></p>
<p>
</table></p>
<p> </xsl:template></p>
<p> <xsl:template match="Person"></p>
<p>
<tr></p>
<p>
<td><xsl:value-of select="Name"/></td></p>
<p>
<td><xsl:value-of select="Age"/></td></p>
<p>
<td><xsl:value-of select="Gender"/></td></p>
<p>
<td><xsl:value-of select="PostalCode"/></td></p>
<p>
</tr></p>
<p></xsl:stylesheet></p>
Once the stylesheet exists, the ASP code can load both the XML data and the XSL file. We reuse the same Microsoft.FreeThreadedDOMDocument object for each file, then apply the transformation in a loop that writes the output to the response stream.
<p>' Load the XML document</p>
<p>Dim xmlDoc, xslDoc</p>
<p>xmlDoc.async = False</p>
<p>' Load the XSL stylesheet</p>
<p>Set xslDoc = Server.CreateObject("Microsoft.FreeThreadedDOMDocument")</p>
<p>xslDoc.async = False</p>
<p>xslDoc.load Server.MapPath("person.xsl")</p>
<p>' Prepare a node set that selects all Person nodes</p>
<p>Dim personNodes, i, nodeCount, currentNode</p>
<p>Set personNodes = xmlDoc.selectNodes("//Person")</p>
<p>nodeCount = personNodes.length</p>
<p>' If there are records, transform each and output</p>
<p>If nodeCount > 0 Then</p>
<p>
For i = 0 To nodeCount - 1</p>
<p>
Set currentNode = personNodes(i)</p>
<p>
Response.Write currentNode.transformNode(xslDoc)</p>
<p>
Next</p>
<p>Else</p>
<p>
Response.Write "<p>No records found.</p>"</p>
<p>End If</p>
<p>%>
The selectNodes method returns a collection of all Person elements. Each element is passed individually to transformNode, which runs the XSLT against the single node. The stylesheet’s root template generates the entire table, so the output of each transformNode call is a complete HTML table. Because the stylesheet’s top template matches the PersonList root, you can also call transformNode once on the root node if you prefer a single table that contains all records.
If you prefer a single table that holds all people, simply change the transformation call to:
Response.Write xmlDoc.transformNode(xslDoc)</p>
In that case the XSL stylesheet must match the root element, as it does in the example. The result is a neatly formatted table that lists every person you have added. You can further enhance the styling with CSS or add links to edit or delete entries, but the core idea remains the same: read the XML, apply XSL, and stream the HTML to the browser.
With the form, the ASP processing routine, and the XSL renderer in place, you have a complete cycle: users submit data, the server writes it to XML, and the same data is shown back to them as a tidy table. This architecture works well for small applications or prototypes and demonstrates how classic ASP can cooperate with XML and XSLT without the overhead of a full database.
If you want to experiment further, download the bundled ZIP file that contains the form page, the ASP logic, the XML file, and the XSL stylesheet. Open the folder in your favorite editor, make a few changes, and then test it in a local IIS environment. Tweaking the XSL can turn the simple table into a responsive layout, while adding more fields to the form can demonstrate how XML grows to accommodate new data types. Happy coding!





No comments yet. Be the first to comment!