Jump to content

Reading Nested Xml With Javascript


jqwerty
 Share

Recommended Posts

Hi All, I am very new to Javascript & XML and have been asked by my daughters school to put together a webpage so they can sell their shirts and whatnot. I've decided to use XML to make it easier for others to manage what is added, etc. I'm able to get almost everything showing on the screen but where I'm running into an issue is where I use a drop-down box to display the sizes (not all items have sizes). Here is my XML file:

<?xml version="1.0" encoding="ISO-8859-1"?><CATALOG>	<CD id="18600">		<FILNM>18600.png</FILNM>		<TITLE>Royal Blue Full Zip Hoodie</TITLE>		<ITMNO>18600</ITMNO>		<PRICE>$20.00</PRICE>		<DETAL>You can look great, stay toasty-warm and show your School Spirit in this soft zip-up fleece hooded sweatshirt. 8 oz. fleece blend (80% cotton/20% polyester), Cotton/Spandex blend at waistband and ribbed cuffs and Jam resistant metal zipper.</DETAL>		<SIZE>			<DESC>Youth Small</DESC>			<COST>$20.00</COST>			<DESC>Youth Medium</DESC>			<COST>$20.00</COST>			<DESC>Youth Large</DESC>			<COST>$20.00</COST>			<DESC>Adult Small</DESC>			<COST>$20.00</COST>			<DESC>Adult Medium</DESC>			<COST>$20.00</COST>			<DESC>Adult Large</DESC>			<COST>$20.00</COST>			<DESC>Adult X-Large</DESC>			<COST>$20.00</COST>			<DESC>Adult 2X-Large</DESC>			<COST>$22.00</COST>			<DESC>Adult 3X-Large</DESC>			<COST>$23.00</COST>		</SIZE>	</CD>	<CD id="STICKER">		<FILNM>sticker.png</FILNM>		<TITLE>Bumper Sticker</TITLE>		<ITMNO>STICKER</ITMNO>		<PRICE>$2.00</PRICE>		<DETAL>OCS Bumper Sticker</DETAL>	</CD></CATALOG>

<script type="text/javascript">if (window.XMLHttpRequest)  {  xhttp=new window.XMLHttpRequest();  }else // Internet Explorer 5/6  {  xhttp=new ActiveXObject("Microsoft.XMLHTTP");  }xhttp.open("GET","spirit_wear.xml",false);xhttp.send("");xmlDoc=xhttp.responseXML; document.write("<table border='0' width='100%' cellpadding='3' cellspacing='3'>");var x=xmlDoc.getElementsByTagName("CD");for (i=0;i<x.length;i++)  {   document.write("<tr><td align=center valign=top><img src='spiritwear/");  document.write(x[i].getElementsByTagName("FILNM")[0].childNodes[0].nodeValue);  document.write("' alt='");  document.write(x[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue);  document.write("' border=0><br />");  document.write("</td><td align=left valign=top><font size=4><b>");  document.write(x[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue);  document.write("</b></font><br /><br />");  document.write("<font color=red size=1 face='arial,tahoma'>Starting Price</font> ");  document.write("<font size=4><b>");  document.write(x[i].getElementsByTagName("PRICE")[0].childNodes[0].nodeValue);  document.write("</b><br /><br />");  document.write("<form target='paypal' action='https://www.paypal.com/cgi-bin/webscr' method='post'>");  document.write("<input type='hidden' name='cmd' value='_cart'>");  document.write("<input type='hidden' name='business' value='collector00@gmail.com'>");  document.write("<input type='hidden' name='lc' value='US'>");  document.write("<input type='hidden' name='item_name' value='");  document.write(x[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue);  document.write("'>");  document.write("<input type='hidden' name='item_number' value='");  document.write(x[i].getElementsByTagName("ITMNO")[0].childNodes[0].nodeValue);  document.write("'>");  document.write("<input type='hidden' name='button_subtype' value='products'>");  document.write("<input type='hidden' name='currency_code' value='USD'>");  document.write("<input type='hidden' name='add' value='1'>");  document.write("<input type='hidden' name='bn' value='PP-ShopCartBF:btn_cart_SM.gif:NonHostedGuest'>");  document.write("<input type='hidden' name='on0' value='Size'>");  document.write("<input type='hidden' name='currency_code' value='USD'>");  document.write("<font size=2 face='arial,tahoma'><b>Select Size:</b> ");  document.write("<select name='os0'>");  document.write("<option value=''>--- select size ---");  var a=xmlDoc.getElementsByTagName("SIZE");  for (z=0;z<a.length;z++)	{	document.write("<option value='");	document.write(a[z].getElementsByTagName("DESC")[0].childNodes[0].nodeValue);	document.write("'>");	document.write(a[z].getElementsByTagName("DESC")[0].childNodes[0].nodeValue);	document.write(" ");	document.write(a[z].getElementsByTagName("COST")[0].childNodes[0].nodeValue);	}  document.write("</select></font>");  document.write("<br /><font size=1 face='arial,tahoma'>Item # ");  document.write(x[i].getElementsByTagName("ITMNO")[0].childNodes[0].nodeValue);  document.write("</font>");  document.write("<br /><br /><font size=2 face='arial,tahoma'><b>Product Details</b><br /><font size=2>");  document.write(x[i].getElementsByTagName("DETAL")[0].childNodes[0].nodeValue);  document.write("</font><br />");  document.write("<input type='hidden' name='option_index' value='0'><br />");  document.write("<input type='image' src='images/addtocart.gif' border='0' name='submit' alt='Make payments with PayPal - it's fast, free and secure!'>");  document.write("</form>");  document.write("</td></tr>");  document.write("<tr><td colspan=2><hr /></td></tr>");  }document.write("</table>");</script>

The above javascript actually displays the FIST description and price of each item. If anyone has a solution, I'm sure its something stupid that I'm missing but I just cannot figure it out. I would greatly appreciate any assistance! If my code is messy, I apologize....I did my best :)THANK YOU IN ADVANCE!!

Link to comment
Share on other sites

1. Stop using document.write(). This might not be the right project for that, but really it's a must. No one seriously creates a whole web page in this manner.2. You only have one size element! So you're looping through exactly one element. Not your intention. Better to look like this:

<SIZE>	<DESC>Youth Small</DESC>	<COST>$20.00</COST></SIZE><SIZE>	 <DESC>Youth Medium</DESC>	 <COST>$20.00</COST></SIZE>etc.

Now, each size element contains a description and the cost, and your collection of size elements will be as long as your list of products. Looping through the size collection should work correctly.

Link to comment
Share on other sites

1. Stop using document.write(). This might not be the right project for that, but really it's a must. No one seriously creates a whole web page in this manner.
I'm not sure I know any other method to doing this at this time.
2. You only have one size element! So you're looping through exactly one element. Not your intention. Better to look like this:
<SIZE>	<DESC>Youth Small</DESC>	<COST>$20.00</COST></SIZE><SIZE>	 <DESC>Youth Medium</DESC>	 <COST>$20.00</COST></SIZE>etc.

Thank you for the quick response, unfortunately this produces the same list of sizes for each item. For example ShirtA may have Small, Med, Lrg and ShirtB may come in Adult Small only. When I create the XML as you said, EVERY ITEM shows Small, Med, Lrg, Adult Small. It also displays the prices for each item, regardless whether its ShirtA or ShirtB. I would like to have a specific list of sizes per item (some items don't have a size, like a bumper sticker or bag so the size would be blank) and price.
Link to comment
Share on other sites

The problem is in this line:

var a=xmlDoc.getElementsByTagName("SIZE");

This returns a master list of every SIZE element in the document. What you want is a list of every SIZE element in the product. If there are zero sizes, then your SIZE loop shouldn't even trigger. (In fact, if you tested the SIZE length a few lines earlier, you could keep the SIZE <select> box from printing when theirt are zero sizes.)Anyway, I think this small change, which I'm sure you just over looked, will clear things up:

a=x[i].getElementsByTagName("SIZE")

You don't want to declare a as a var inside a loop, BTW. Declare it at the top of your page, once only. Some browsers will throw an error if you try to re-declare a var.This puts a few of those ideas together:

a = x[i].getElementsByTagName("SIZE");len = a.length;if (len) {  document.write("<select name='os0'>");  document.write("<option value=''>--- select size ---");  for (z = 0; z < len; z++)  {	document.write("<option value='");	document.write(a[z].getElementsByTagName("DESC")[0].childNodes[0].nodeValue);	document.write("'>");	document.write(a[z].getElementsByTagName("DESC")[0].childNodes[0].nodeValue);	document.write(" ");	document.write(a[z].getElementsByTagName("COST")[0].childNodes[0].nodeValue);  }  document.write("</select>";}document.write("</font>");

Again, this will only work if you go with the reorganization of your XML as I showed you in my first post, because we still need to eliminate the problem that was bugging you the first time around.

Edited by Deirdre's Dad
Link to comment
Share on other sites

Wow, that was really good and simple (for you to figure out). I really want to thank you because I've been racking my head for days trying to figure all this out and none of the samples I've seen online addressed this issue...or I wasn't using the correct lingo to search for it. One thing...
  document.write("</select>";

You forgot to include the closing paranthasis. I figured you were just trying to test me.Again, thanks!

Link to comment
Share on other sites

EDIT: Was in mid-post when you replied. Sorry about the paren. I changed that line in a rush, I guess. Hope you can still learn something from this. And no, it wasn't much trouble:This is not the whole thing, but shows you how to integrate some HTML DOM techniques with XML DOM techniques. You can modify it and expand it as you see fit. I think you'll appreciate dumping all those document.write() statements and not having to keep track of multiple levels of quotation marks. You also get to see a couple of nice tricks.Tested in Firefox, Safari, Opera, IE7Its success depends on the modified XML format we discussed, and I've included a partial file to show you.Of course, this would be a lot easier if we parsed the XML on your server. OTOH, with a very few adjustments, this can be modified to download and build product tables from other XML files on the fly. So it could be a pretty robust storefront if you ever wanted to expand the line for any reason.document

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"   "http://www.w3.org/TR/html4/strict.dtd"><html>	<head>		<meta http-equiv="content-type" content="text/html;charset=UTF-8">		<title></title>		<style type="text/css">			#productList tr.white {				background-color: #fff;			}			#productList tr.blue {				background-color: #ccf;			}			#productList td {				padding: 3px;			}		</style>		<script type="text/javascript">			var xhttp, xmlDoc;			function is_odd(n) {				return n & 1;			}			function get_node_value (n) {				// returns empty string (instead of error) if no text node exists				return n.childNodes[0] ? n.childNodes[0].nodeValue : "";			}			function insert_option (sel) {				var err;				var opt = document.createElement('option');				try {					sel.add (opt, null);				} catch (err) {					sel.add (opt);				}				return opt;			}			function getXhttp () {				if (window.XMLHttpRequest) {					xhttp=new window.XMLHttpRequest();				}				else {					xhttp=new ActiveXObject("Microsoft.XMLHTTP");				}				return xhttp;			}			function getXML () {				xhttp = getXhttp();				if (!xhttp) {					return false;				}				xhttp.open("GET","spirit_wear.xml",false);				xhttp.send("");				return xhttp.responseXML; 			}			function buildTable () {				var i, j, myRow, myCell, sLen, sizes, mySelect, myOpt, myTxt, myVal;				var products = xmlDoc.getElementsByTagName("CD");				var pLen = products.length;				var myTable = document.getElementById("productList");				for (i = 0; i < pLen; ++i) {					myRow = myTable.insertRow(i);					myRow.className = is_odd(i) ? "blue" : "white";					myCell = myRow.insertCell(0);					myCell.innerHTML = get_node_value(products[i].getElementsByTagName("FILNM")[0]);					myCell = myRow.insertCell(1);					myCell.innerHTML = get_node_value(products[i].getElementsByTagName("TITLE")[0]);					myCell = myRow.insertCell(2);					myCell.innerHTML = get_node_value(products[i].getElementsByTagName("PRICE")[0]);					myCell = myRow.insertCell(3);					sizes = products[i].getElementsByTagName("SIZE");					sLen = sizes.length;					if (sLen) {						mySelect = document.createElement('select');						for (j = 0; j < sLen; ++j) {							myVal = get_node_value(sizes[j].getElementsByTagName("DESC")[0]);							myTxt = myVal + " " + get_node_value(sizes[j].getElementsByTagName("COST")[0]);							myOpt = insert_option(mySelect);							myOpt.value = myVal;							myOpt.text = myTxt;						}						myCell.appendChild(mySelect);					}				}			}			function main () {				xmlDoc = getXML();				if (!xmlDoc) {					return;				}				buildTable();			}			window.onload = main;		</script>	</head>	<body>		<table>			<!-- tbody ensures compatibility -->			<tbody id="productList"></tbody>		</table>	</body></html>

xml

<?xml version="1.0" encoding="ISO-8859-1"?><CATALOG>	<CD id="18600">		<FILNM>18600.png</FILNM>		<TITLE>Royal Blue Full Zip Hoodie</TITLE>		<ITMNO>18600</ITMNO>		<PRICE>$20.00</PRICE>		<DETAL>You can look great, stay toasty-warm and show your School Spirit in this soft zip-up fleece hooded sweatshirt. 8 oz. fleece blend (80% cotton/20% polyester), Cotton/Spandex blend at waistband and ribbed cuffs and Jam resistant metal zipper.</DETAL>		<SIZES>			<SIZE>				<DESC>Youth Small</DESC>				<COST>$20.00</COST>			</SIZE>			<SIZE>				<DESC>Youth Medium</DESC>				<COST>$20.00</COST>			</SIZE>			<SIZE>				<DESC>Youth Large</DESC>				<COST>$20.00</COST>			</SIZE>			<SIZE>				<DESC>Adult Small</DESC>				<COST>$20.00</COST>			</SIZE>			<SIZE>				<DESC>Adult Medium</DESC>				<COST>$20.00</COST>			</SIZE>			<SIZE>				<DESC>Adult Large</DESC>				<COST>$20.00</COST>			</SIZE>			<SIZE>				<DESC>Adult X-Large</DESC>				<COST>$20.00</COST>			</SIZE>			<SIZE>				<DESC>Adult 2X-Large</DESC>				<COST>$22.00</COST>			</SIZE>			<SIZE>				<DESC>Adult 3X-Large</DESC>				<COST>$23.00</COST>			</SIZE>		</SIZES>	</CD>	<CD id="STICKER">		<FILNM>sticker.png</FILNM>		<TITLE>Bumper Sticker</TITLE>		<ITMNO>STICKER</ITMNO>		<PRICE>$2.00</PRICE>		<DETAL>OCS Bumper Sticker</DETAL>	</CD></CATALOG>

Edited by Deirdre's Dad
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...