Inside Microsoft Web Bulder

July 1999

Passing Structured Data with XML and IE 5

by Bill Pitzer

With Internet Explorer 5, Microsoft has made some great strides in developing a browser that fully supports the W3C's XML 1.0 standard. So what does this mean to those that are unfamiliar with XML? HTML is a great standard language for delivering content to users, but in the past most data collection and manipulation was accomplished by sending requests to the server.

Using client-side XML, applications now have the capability to pass structured data among different applications, regardless of where this data is found. In this article, we'll revise the application we created in the article "Persistence and the userData behavior in IE 5" and show you how to use XML to pass structured data between multiple pages.

Changing times call for changing attributes

In the accompanying article on data persistence, we showed you a simple example in which customer information was maintained across a few Web pages. For simplicity, we explicitly defined all the stored data as attributes. However, let's pretend we had different pieces of information we wanted to group together. Suppose, in addition to basic customer information, we wanted to store certain personal information, as well.

Look at Figure A for our revised customer information form. Notice that three new fields have been added: age, favorite band, and favorite food.

Figure A: This is the familiar customer information form, but now with a few extra fields.
[ Figure A ]

The original code for this page is found in the article "Persistence and the userData behavior in IE 5" in Listing A. Here, Listing A shows the statements you'll need to add to that BODY code to create the page in Figure A.

Listing A: Code to add to the original BODY code to create the new page in Figure A


<P><FONT size=2><STRONG><U>Other 
Information:</U></STRONG></FONT></p>
<P>
<TABLE>
<TR>
<TD><STRONG>Age:</STRONG></TD>
<TD><INPUT class=userData id=customer_age 
style="HEIGHT: 22px; WIDTH: 39px"></TD></TR>
<TR>
<TD><STRONG>Favorite Band:</STRONG></TD>
<TD><INPUT class=userData id=customer_band 
style="HEIGHT: 22px; WIDTH: 215px"></TD></TR>
<TR>
<TD><STRONG>Favorite Food:</STRONG></TD>
<TD><INPUT class=userData id=customer_food 
style="HEIGHT: 22px; WIDTH: 216px"></TD></TR>
</TABLE></p>

XML structure, please

Now we need to represent all of our data in XML. XML is based upon its own Document Object Model (DOM). Like other object models, it can be thought of as a tree-like structure with a root node and children descending down from it. Once the structure has been created, using the XMLDocument property on a persistent object exposes the entire XML DOM.

To represent our data in XML, we'll break it down the way it appears on our page in Figure A. Instead of simply using attributes for all the data, we'll segment it into address information and other information. Putting it into XML would look something like Listing B.

Listing B: XML code for representing the data values in Figure A


<CUSTOMER_INFORMATION>
<ADDRESS_INFORMATION>
<NAME>Johnny Readalot</NAME>
<ADDRESS>18 Bookworm Lane</ADDRESS>
<CITY>Cincinnati</CITY>
<STATE>OH</STATE>
<PHONE>555-5555</PHONE>
</ADDRESS_INFORMATION>
<OTHER_INFORMATION>
<AGE>55</AGE>
<FAVORITE_BAND>Weird Al Yankovic</FAVORITE_BAND>
<FAVORITE_FOOD>Chili</FAVORITE_FOOD>
</OTHER_INFORMATION>
</CUSTOMER_INFORMATION>

A different DOM

Just like HTML, you must have beginning and end tags surrounding each piece of data. However, remember that XML tags actually describe the data contained within them rather than defining display properties the way that HTML does.

If you look closely, you'll see that we have nested tags. This enables some of the structure XML provides. Think of CUSTOMER INFORMATION as the root of the structure with all the other data branching off and you've got the idea.

The power of (XML) Notepad

Microsoft has made it easier to create your XML code, with something called XML Notepad. XML Notepad is a very easy to use and tiny (around 300 KB) application that makes setting up an XML structure a snap. Use it to create child elements, add attributes, or whatever else you'll need to enter.

The XML code in Listing B was developed using the XML Notepad's GUI interface in about five minutes. Seeing how it looks when it's done in XML Notepad will also help you understand the structure, if you're having trouble. Figure B shows how the data in our example would look using this application. Download XML Notepad from Microsoft's site at msdn.microsoft.com/msdn-online/workshop/xml/notepad/download.asp.

Figure B: XML Notepad is an easy way to tame those XML structures.
[ Figure B ]

Say it with script

How you get your XML structure into your page is up to you. Using the methods and properties of an XMLDocument object, it can be done entirely with script. Let's step through how we would create the main XML document and it related data items.

First, we need to set a reference to the XMLDocument object:



var XMLDoc = 
	customer_info_div.XMLDocument;

This is the top-most node in our collection, represented by the CUSTOMER_INFORMATION item. Next, we create a reference to root element of this document tree:

var document_element = 
	XMLDoc.documentElement;

Then, add a new child node underneath the document object by first creating a new child element:

var address_info_element = 
	XMLDoc.createElement(
	=>"address_information");

Then, add the element under the topmost document element to the childNodes collection of the CUSTOMER_INFORMATION node:

var customer_address_element = 
	document_element.appendChild(
	=>address_info_element);
This could be repeated to set up the rest of the nodes that fall into the structure. Just be sure you're appending your children to the right parent node.

If you had data from another source, such as an Access database, you could systematically load the tree as appropriate. Since all of our data comes from input boxes, we'll have to repeat the last two steps for every piece of data we need to add. The script behind the new takeme_button_onclick event does exactly that. The code is shown in Listing C.

Listing C: Function to place the XML structure into our page



function takeme_button_onclick() {

	//Create a reference to the main XML Document.
	var XMLDoc = customer_info_div.XMLDocument;

	//Create a reference to the document element.
	var document_element = XMLDoc.documentElement;

	//Create the "top" element tag for address info.
	var address_info_element = 
		XMLDoc.createElement("address_information");

	//Create the "top" element tag for other info.
	var other_info_element = 
		XMLDoc.createElement("other_information");

	//Append these elements as "branches" under the main 
	//document.
	var customer_address_element = 
	document_element.appendChild(address_info_element);
	var customer_info_element = 
	document_element.appendChild(other_info_element);

	//Create the elements under the "Address Info" branch.

	var customer_name_element = 
		XMLDoc.createElement("customer_name");
	var new_name_element = 
		customer_address_element.appendChild(
		=>customer_name_element);
	new_name_element.text = customer_name.value;

	var customer_addr_element = 
		XMLDoc.createElement("customer_address");
	var new_addr_element = 
		customer_address_element.appendChild(
		=>customer_addr_element);
	new_addr_element.text = customer_address.value;

	var customer_city_element = 
		XMLDoc.createElement("customer_city");
	var new_city_element = 
		customer_address_element.appendChild(
		=>customer_city_element);
	new_city_element.text = customer_city.value;

	var customer_state_element = 
		XMLDoc.createElement("customer_state");
	var new_state_element = 
		customer_address_element.appendChild(
		=>customer_state_element);
	new_state_element.text = customer_state.value;

var customer_phone_element = 
	XMLDoc.createElement("customer_phone");
	var new_phone_element = 
		customer_address_element.appendChild(
		=>customer_phone_element);
	new_phone_element.text = customer_phone.value;

	//Create the elements under the "Other Info" branch.
	var customer_age_element = 
		XMLDoc.createElement("customer_age");
	var new_age_element = 
		customer_info_element.appendChild(
		=>customer_age_element);
	new_age_element.text = customer_age.value;

	var customer_food_element = 
		XMLDoc.createElement("customer_food");
	var new_food_element = 
		customer_info_element.appendChild(
		=>customer_food_element);
	new_food_element.text = customer_food.value;

var customer_band_element = 
	XMLDoc.createElement("customer_band");
	var new_band_element = 
		customer_info_element.appendChild(
		=>customer_band_element);
	new_band_element.text = customer_band.value;	

	//Save it into the store.
	customer_info_div.save("MyXMLStore");

	//Open up a new page.
	location.href="xml_magazine_man.htm";
}

Use the DOM, Luke

If you recall in the example in our persistence article, we have a magazine subscription Web site where visitors entered some basic information on the first page. When they were finished, the page transported them to another page while maintaining the information they entered.

We've now added more information and structured it a little differently than before. We must now be able to get at this data on the second page. Let's do it systematically using our newly exposed XML Document Object Model. The function window_onload in Listing D contains the code.

The first thing we need to do is load the XML code onto our page. If we have our XML script already defined, there's no need to write a lot of script to accomplish this. The XMLDOMDocument has two methods to load your XML code: load and loadXML.

The load method simply accepts the URL to your already-defined XML page. The loadXML method accepts one parameter as well: a string containing your actual XML script. Both of these functions return true or false to indicate whether or not the load was successful.

Now, to actually get the data. Looking back at the XML code in Listing B, you'll notice that we've defined two main elements: ADDRESS_INFORMATION and OTHER_INFORMATION. These elements correspond to the physical sections that have been defined on the form. Traversing the XML DOM, we must first define a reference to these top-most elements. From there, we can access each child node specifically.

Each piece of data is described by the nodeName property we set for it. From there, we can retrieve the value in each element by accessing the text property for that nodeName. The length property is also very important. It tells us exactly how many childNodes have been defined under each element. In the window_onload event in Listing D, you'll see the nested for loops that accomplish this.

Listing D: Function to traverse the XML Document Object Model and retrieve the data.



function window_onload() {
	//Load the userdata store.
	customer_info_div.load("MyXMLStore");

	//Set a reference to the main XML document.
	var xmldoc = customer_info_div.XMLDocument;

	//Set a reference to the element.
	var xml_doc_element = xmldoc.documentElement;

	//Set a reference to the collection of child nodes
	//under the main document.
	var xml_nodes = xml_doc_element.childNodes;

	//Get number of items in the collection.
	var node_count = xml_nodes.length;
	
	//Clear out the display text just to be safe.
	var customer_info = ";
		
	//Iterate through all the nodes and build a string 
	//of node names and the attributes contained in each.
	for (x=0; x<node_count; x++) {
		//Add the node name.
		var current_node = xml_nodes.item(x);
		customer_info += "<STRONG>" + current_node.nodeName + 
			":</STRONG><BR>";
		new_node_count = current_node.childNodes.length;
		for (y=0; y<new_node_count; y++) {
			customer_info += "&nbsp;" + 
		current_node.childNodes.item(y).nodeName + ":" +
		current_node.childNodes.item(y).text + "<BR>";
		}
	}
	
	//Replace the information between the DIV tags.
	customer_info_div.innerHTML = customer_info;
}
The code in Listing D constructs a string containing all the elements we want displayed on the screen. Look at Figure C to see what the finished product looks like.

Figure C: This page displays the data from the XML store.
[ Figure C ]

Don't forget about the server!

XML and its ability to provide structure for your data on the client side are the cause for much excitement in the Web community. However, don't forget that XML can also be used on the server, allowing you to pass structured data between the client and the server as well.

Using the XML engine found in IE 5, you can then instantiate the object on the server from your scripts. This is a great way to provide XML to clients that use a browser that may not currently support XML. Examples of how to use his powerful method can be found on Microsoft's site at http://msdn.microsoft.com/xml/guide/server-overview.asp

There are, however, security issues to consider when transporting XML data across domains, protocols, and zones. Read about the specifics in the "XML Security Developers Guide" at http://msdn.microsoft.com/xml/guide/security.asp.

XML excitement is building

XML's power lies in its flexible and open format. The W3C has been working hard to standardize the language and provide methods, such as schema support, to help manage its content. The W3C XML Activity site can keep you informed of the latest developments at www.w3.org/XML/Activity.html

A great place to start your research on how to manipulate the DOM using a script language can be found in the "XML DOM User Guide" on Microsoft's site at http://msdn.microsoft.com/xml/guide/dom-guide-overview.asp

And, upcoming articles in Microsoft Web Builder will cover different facets of this powerful and evolving extension to HTML as well.

Copyright © 1999, ZD Inc. All rights reserved. ZD Journals and the ZD Journals logo are trademarks of ZD Inc. Reproduction in whole or in part in any form or medium without express written permission of ZD Inc. is prohibited. All other product names and logos are trademarks or registered trademarks of their respective owners.