Charles Heinemann
Happy Days Are Here Again: Posting XML to the Server
Posted July 17, 1998 To be archived August 17, 1998
Download Microsoft Word (.DOC) format of this document (zipped, 12.2K)
Confounded by what the English find entertaining, I've resorted to a more American pastime: the TV Guide Crossword. My ability to recall who played the role of Potsie Weber has my confidence swelling. Less successful has been my quest to sell subscriptions to my new information service (as outlined in my last column). Never did I think it would be this tough to squeeze a few nickels out of my relatives.
I began by doing a little cold-calling, but everyone I got on the horn was either in the middle of dinner, confused me with a long-distance sales representative, or had, at some point, done business with my old man.
This experience soon led me to the conclusion that I needed to refocus my efforts. Instead of randomly contacting kin, I decided to concentrate on only the most savvy of family members. To do this, I had to make up a list of potential subscribers, classifying each as "No Vision," "Will Bite," or "Dupe," depending on each's willingness to take that extra step toward improving his or her information situation.
I figured I could mark that list up in XML and store it on the server. I would, however, need an easy way to update the list from the client (allowing for the addition of in-laws, uncles who've recently crawled out of the woodwork, and for the editing of any known relatives who change status). So, I constructed a user interface out of HTML, through which I could enter the data concerning a certain relative. I could then package that data as an XML fragment and post it to the server. Once on the server, the data could be parsed and used to update the XML file on the server.
The XML file on the server is a simple set of "customer" elements:
<customers>
<customer>
<name>Hester Heinemann</name>
<relation>Great Aunt</relation>
<class>No Vision</class>
</customer>
<customer>
<name>Cleo Heinemann</name>
<relation>Nephew</relation>
<class>Will Bite</class>
</customer>
<customer>
<name>Luanne Vincent</name>
<relation>Cousin</relation>
<class>No Vision</class>
</customer>
<customer>
<name>Mertle Matthews</name>
<relation>Grandmother</relation>
<class>No Vision</class>
</customer>
<customer>
<name>Uncle Bud</name>
<relation>Second Cousin</relation>
<class>Dupe</class>
</customer>
</customers>
The UI is a couple of text boxes, a select box, and a button:
The user-entered data creates an XML fragment and that fragment is posted to the server through a FORM. The FORM has a single INPUT element of type HIDDEN that, on submission, posts the value of the INPUT element to the Active Server Pages file "postCust.asp":
<FORM NAME=postForm METHOD=POST
ACTION="postCust.asp">
<INPUT TYPE=HIDDEN NAME=postInput>
</FORM>
I could have simply placed this form within the BODY of the page that held the UI. This would result, however, in the UI being replaced by the HTML page returned by postCust.asp. The key to preserving the UI is hiding both the form and the HTML page generated by the .asp file. This can be done through a hidden IFRAME. Below is the BODY of the HTML page used to both create the UI and hide the FORM:
<H1>Customer List Builder</H1>
<IFRAME style="display:none" ID=formHolder
SRC="postCust.asp">
</IFRAME>
<P>Enter Customer Name:
<INPUT TYPE=TEXT NAME=custName>
<BR>Enter Relation to Self:
<INPUT TYPE=TEXT NAME=custRelation>
<BR>Select Customer Classification:
<SELECT NAME="custClass" SIZE=1>
<OPTION SELECTED VALUE="No Vision">No Vision
<OPTION VALUE="Will Bite">Will Bite
<OPTION VALUE="Dupe">Dupe
</SELECT>
<BR>
<INPUT TYPE=button
VALUE="Post Customer Information"
onclick="submitInfo()">
<XML ID=newCustomer></XML>
The file postCust.asp contains not only the script to process and save the XML posted to the server, but also the HTML to generate the FORM and the template used by the application to create the XML fragment:
<%@LANGUAGE=VBScript%>
<%
XMLSTRING = Request.Form("postInput").item
Set NEWCUSTINFO = Server.CreateObject("Microsoft.XMLDOM")
NEWCUSTINFO.loadXML(XMLSTRING)
Set CUSTLIST = Server.CreateObject("Microsoft.XMLDOM")
CUSTLIST.load("c:\inetpub\wwwroot\customers.xml")
If (XMLSTRING <> "") Then
Set CUSTROOT = CUSTLIST.documentNode
Set CUSTOMERS = CUSTROOT.childNodes
Set NEWCUSTROOT = NEWCUSTINFO.documentNode
For I=0 To CUSTOMERS.length - 1
If (CUSTOMERS.item(I).childNodes.item(0).nodeValue =
NEWCUSTROOT.childNodes.item(0).nodeValue) Then
CUSTROOT.removeNode(CUSTOMERS.item(I))
Exit For
End If
Next
CUSTROOT.insertNode(NEWCUSTROOT)
SAVEDXML = CUSTLIST.saveNode(CUSTROOT)
Set FS = CreateObject("Scripting.FileSystemObject")
Set CUSTFILE = FS.CreateTextFile("c:\customers.xml",True)
CUSTFILE.WriteLine(SAVEDXML)
CUSTFILE.Close
End If
%>
<HTML>
<BODY>
<FORM NAME=postForm METHOD=POST
ACTION="postCust.asp">
<INPUT TYPE=HIDDEN NAME=postInput>
</FORM>
<XML ID="template">
<customer>
<name/>
<relation/>
<class/>
</customer>
</XML>
</BODY>
</HTML>
The script within postCust.asp takes the XML fragment and parses it, using the loadXML method. This converts the string to an XML node. The file containing the customer list (customers.xml) is then loaded and parsed. If data has been posted to the server, the XML fragment and the "customer" elements within the customer list are compared to see if the names match. If there is a match, the old node is removed and the fragment takes its place. If there is no match, the fragment is simply inserted into the tree. Following insertion of the node, the tree is turned into a text string using the saveNode method, and that text string is written to the customers.xml file. This process overwrites the previous text within the file, effectively updating the file.
The HTML within the file postCust.asp generates a page containing the form and an XML data island that will act as a template for the XML fragment. This HTML page is generated both when the HTML page containing the IFRAME is loaded and when the FORM is submitted.
The only thing left to do is write a script that will create an XML fragment and then post that fragment to the server. Using the data island now within the IFRAME as a template, the values within the data island are set using the data entered by the user. The data island with the ID value of "newCustomer" is then used to call the saveNode method, converting the "customer" document object to a string. The value of the INPUT element within the FORM is then set to that string, and the FORM is submitted.
function submitInfo(){
var customer = formHolder.template.documentNode;
customer.childNodes.item(0).nodeValue = custName.value;
customer.childNodes.item(1).nodeValue = custRelation.value;
customer.childNodes.item(2).nodeValue = custClass.value;
var xmlString = newCustomer.saveNode(customer);
formHolder.postForm.postInput.value = xmlString;
formHolder.postForm.submit();
}
With my new Web application, I created an XML document containing information on over 40 potential subscribers. There is information on everyone from Ol' Granny Vincent to Poor Ol' Cousin Richie. Looking at the list, a portion of which appears earlier in this article, I think it's safe to say that, as a group, the men in the family seem to possess greater subscriber potential. They seem to be the risk takers, the kind of folks who know a good deal when they see it. Consequently, it is they who I will target once dinnertime rolls around.
So, until then, I suppose I'll get back to my puzzle. By the way, if anyone out there knows who played the role of Ralph Malph, please write.
© 1998 Microsoft Corporation. All rights reserved. Terms of use.
|