Introduction
This example assumes that you are familiar with ASP, XML and HTML 4.0.
Data stored in XML files can easily be edited from the Web
This article is a follow up to the Saving HTML Form Data to XML article. If you have not read Saving HTML Form Data to XML, I suggest that you do so now. This article builds upon it. I have received pretty positive feedback on the Saving HTML Form Data to XML sample, but many people wanted to know how to edit the XML data. So, without further ado, here it is: Editing XML with XSL and ASP.
Using XSL it is possible to open the XML file that you want to edit and transform it into an HTML form and send it to the browser. The values of the XML elements will be placed as the values of the HTML input fields. After you make the necessary edits, the edited information can be submitted to the server and the XML file updated. Active Server Pages is the medium by which all of this can be accomplished.
The first step is to load the file that you want to edit and display it on the browser in an HTML form. In the sample, XML Transformations on the Server I covered how, using the Microsoft XMLDOM Object, an XML file could be transformed by an XSL file for display. We can use the same technique here to transform the XML file. Lets take a look at the XML and XSL files that will be used.
XML File: contact.xml:
<?xml version="1.0" ?> <contact> <field id="firstName" taborder="1"> <field_value>Michael</field_value> </field> <field id="lastName" taborder="2"> <field_value>Qualls</field_value> </field> <field id="address1" taborder="3"> <field_value>202 East Haverbrook</field_value> </field> <field id="address2" taborder="4"> <field_value>Oklahoma City, OK 73114</field_value> </field> <field id="phone" taborder="5"> <field_value>4055551234</field_value> </field> <field id="email" taborder="6"> <field_value>[email protected]</field_value> </field> </contact> |
This XML file layout is the same as the one used in the Saving HTML Forms to XML sample. This is so that you will be able to more easily see the corelation between saving to an XML file and then coming back later and editing that same XML file. Now lets move on to the XSL file.
XSL File: contact.xsl:
<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"> <xsl:template match="/"> <html> <body> <form method="post" action="EditContact.asp"> <h1>Edit Contact:</h1> <table border="1" cellpadding="2"> <xsl:for-each select="contact/field"> <tr> <td> <xsl:value-of select="@id"/> </td> <td> <!-- If you copy this listing, make sure that you place all of the code that makes up this HTML text field onto a single line of code, otherwise the XML file will not be transformed properly. -->
</td> </tr> </xsl:for-each> </table> <input type="submit" id="btnSubmit" name="btnSubmit" value="Submit" /> </form> </body> </html> </xsl:template> </xsl:stylesheet> |
This XSL file uses a for-each XSL element to iterate through the elements of the XML file. Starting from the root element, the “id” attribute for each XML “field” element is written to the “id” and “name” attributes of an HTML text field. Also, the value of each “field_value” element from the XML file is written to the “value” attribute of each of the HTML text fields. The end result is that an HTML form containing the values from the XML file will be displayed for editing.
The reason that I take the “id” attribute from the “field” element in the XML file and place it in the “name” and “id” attributes of the HTML text fields in the XSL file is to reduce confusion and to promote naming consistency. A person should be able to easily see which XML fields map to which HTML fields without having to have an intimate knowledge of the code.
Using these two files, we are well on our way to editing the XML file. The XSL file will transform the XML for display in the browser. We could do the transformation on the client, but that would not be a cross-browser friendly solution. Using ASP we will do the transformation on the server. We will also apply the edits to the XML file on the server. All the client will ever get is nicely formatted HTML which should work in any browser.
Example: Editing XML with XSL and ASP
EditContact.asp is where all of the action takes place. There two functions that do the majority of the work for this ASP page. The first is loadXMLFile which loads and transforms the XML file for display. The second is updateXML which applys the edits to the XML file.
ASP File: EditContact.asp:
<% '----------------------------------------------------------- 'The "loadXMLFile" Function accepts two parameters. 'strXMLFile - The path and file name of the XML file. 'strXSLFilee - The path and file name of the XSL file. '----------------------------------------------------------- Function loadXMLFile(strXMLFile, strXSLFile) 'Declare local variables Dim objXML Dim objXSL 'Instantiate the XMLDOM Object that will hold the XML file. set objXML = Server.CreateObject("Microsoft.XMLDOM") 'Turn off asyncronous file loading. objXML.async = false 'Load the XML file. objXML.load(strXMLFile) 'Instantiate the XMLDOM Object that will hold the XSL file. set objXSL = Server.CreateObject("Microsoft.XMLDOM") 'Turn off asyncronous file loading. objXSL.async = false 'Load the XSL file. objXSL.load(strXSLFile) 'Use the "transformNode" method of the XMLDOM to apply the 'XSL stylesheet to the XML document. Then the output is 'written to the client. Response.Write(objXML.transformNode(objXSL)) End Function '----------------------------------------------------------- 'The "updateXML" Function accepts one parameter. 'strXMLFile - The path and file name of the XML file. '----------------------------------------------------------- Function updateXML(strXMLFile) 'Declare local variables. Dim objDom Dim objRoot Dim objField Dim x 'Instantiate the XMLDOM Object. set objDOM = Server.CreateObject("Microsoft.XMLDOM") 'Turn off asyncronous file loading. objDOM.async = false 'Load the XML file. objDOM.load strXMLFile 'Set the objRoot variable equal to the root element of the 'XML file by calling the documentElement method of the 'objDOM (XMLDOM) object. Set objRoot = objDom.documentElement 'Iterate through the Form Collection and write the 'submitted values to the XML file. For x = 1 to Request.Form.Count 'Check see if "btn" is in the submitted value, if so, 'it is a button and should be ignored. If instr(1,Request.Form.Key(x),"btn") = 0 Then 'Set objField variable equal to a field_value element by 'calling the selectSingleNode method of the objRoot '(documentElement) object. The SelectSingleNode method 'accepts a string parameter for querying the XML document. 'In this case, the current value of the key property of 'the Form Collection is used to find the appropriate 'field_value element (more on this later). Set objField = objRoot.selectSingleNode("field[@id='" & _ Request.Form.Key(x) & "']/field_value") 'Set the text property of the objField (field_value) 'element equal to the value of the current form field. objField.Text = Request.Form(x) End If Next 'After the XML file has been edited, is must be saved. objDom.save strXMLFile 'Release all of your object references. Set objDom = Nothing Set objRoot = Nothing Set objField = Nothing 'Call the loadXMLFile method, passing in the newly edited 'XML file and the updatedcontact.xsl style sheet. This will 'allow the client to see the edited information. More on the 'updatedcontact.xsl file later. loadXMLFile strXMLFile,server.MapPath("updatedcontact.xsl") End Function 'Test to see if the form has been submitted. If it has, 'update the XML file. If not, transform the XML file for 'editing. If Request.Form("btnSubmit") = "" Then loadXMLFile server.MapPath("Contact.xml"), _ server.MapPath("contact.xsl") Else updateXML server.MapPath("Contact.xml") End If %> |
As you can see, it is the ASP file that handles the entire process of updating the XML file. If the form is being submitted, the XML file is opened and updated. If the form is not being submitted, then the XML file is loaded and tranformed by contact.xsl into an HTML form so that the user can edit it. Lets take one more look at the following piece of code:
For x = 1 to Request.Form.Count If instr(1,Request.Form.Key(x),"btn") = 0 Then Set objField = objRoot.selectSingleNode("field[@id='" & _ Request.Form.Key(x) & "']/field_value") objField.Text = Request.Form(x) End If Next |
This is the code that does all the work of updating the XML file. The selectSingleNode method is the key. This method queries the XML file for a single node that matches the query that is passed into the function. In this case, the query is “field[@id='”& request.form.key(x) & “‘]/field_value”. What this query is requesting is the field_value element that is the child of a field element that has an id attribute which matches the current key value in the Form Collection. Once the proper node is obtained, then it is just a matter of updating the text property to match the value of the current field in the Form Collection.
Keep another thing in mind, the query always starts from the current context. When the selectSingleMode function is called in this example, it is from the context of the root element of the XML file. Therefore, the root element will be the starting point from which the query is executed.
Finally, lets take a quick look at updatedcontact.xsl. This is the XSL file that is used to display the updated XML data. It is not that different from the contact.xsl file. It simply displays the data for viewing rather than putting it into an HTML form.
XSL File: updatedcontact.xsl:
<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"> <xsl:template match="/"> <html> <body> <h1>Updated Contact Information:</h1> <table border="1" cellpadding="2"> <xsl:for-each select="contact/field"> <tr> <td> <xsl:value-of select="@id" /> </td> <td> <xsl:value-of select="field_value" /> </td> </tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet> |
This XSL file simply iterates through the XML file building a static HTML table that will send the XML file contents to the browser. That is about it. If you use this article and the Saving HTML Form Data to XML, you should be well on your way to using XML for you Web based data storage. As always, I hope that this sample helps! I always welcome feedback! I want to be sure that my articles are helpful (or at least thought provoking)!