Tuesday, February 19, 2008 @ 8:09 PM
Part 6: Taming XML

Though it's easy to get Javascript to read from an XML file, pulling out the appropriate data can sometimes be tricky. Here are some tips to help you tame the XML beast.
Refer to the code we posted yesterday. If the XMLHttpRequest loads without error, then we can use the xmlhttp variable to access the contents of the loaded XML file. To understand how to work with xmlhttp (or whatever you named the XMLHttpRequest instance), relate it to Javascript's document variable.
document.getElementsByName('menu') will return an array of the elements on your page that all share the name "menu."
xmlhttp.responseXML.getElementsByTagName('menu') will return an array of the "menu" XML nodes (tags).
Now, nodes can have both attributes and values. In the following example, "Burns or Byron" is the c attribute of the a1 node and "Timothy Parker" is the value of the editor node.
XML Example:
<?xml version="1.0" encoding="UTF-8"?>
<editor>Timothy Parker</editor>
<across>
<a1 a="POET" c="Burns or Byron" n="1" cn="1" />
</across>
getElementsByTagName will always return an array. In the example above there is only one a1 node, therefore there's no reason to keep an array of a1 nodes. Using the code below, we can save to variable only the first returned node (since that's all that exists).
var a1 = xmlhttp.responseXML.getElementsByTagName('a1')[0];Now, access the c attribute like this:
var c = a1.getAttribute('c');Doing that is easy, but accessing node values is a little more confusing. Here's the code to access the editor node's value:
var editor = xmlhttp.responseXML.getElementsByTagName('editor')[0];
var editorValue = editor.firstChild.nodeValue;The firstChild method gives you access to a node's first child. But the editor node does not appear to have any children. Well, it apparently (or not so apparently) does. When attempting to access the value of a node, imagine the value text as being a node itself... access the nodeValue of the "text node" and you'll get the result you're looking for. Or, in more simple terms, always use .firstChild.nodeValue to access the value of a node.
Another XML Example:
<?xml version="1.0" encoding="UTF-8"?>
<across>
<a1 a="POET" c="Burns or Byron" n="1" cn="1" />
<a2 a="BLAB" c="Give everything away" n="6" cn="5" />
<a3 a="TALKS" c="Gives everything away" n="11" cn="9" />
<a4 a="ALSO" c="Too" n="16" cn="14" />
<a5 a="YOHO" c="Exclamation by Captain Jack Sparrow" n="21" cn="15" />
<a6 a="ELIOT" c="''A Cooking Egg'' writer" n="26" cn="16" />
<a7 a="LIAR" c="Ananias, for one" n="31" cn="17" />
<a8 a="PREY" c="Target in the wild" n="36" cn="18" />
<a9 a="ALONE" c="In isolation" n="41" cn="19" />
</across>
In the above example, all of the across child nodes are named differently, so it would be cumbersome to "getElementsByTagName" each one separately. Instead, take advantage of the childNodes collection to return an array of the nodes.
var across = xmlhttp.responseXML.getElementsByTagName('across')[0].childNodes;There is more to learn about XMLHttpRequest, but by simply knowing how to use the getElementsByTagName, getAttribute, firstChild and nodeValue methods and the childNodes collection, you'll have an easy time accessing all types of data from XML documents.
Before I close this lengthy post, there is one more thing I'd like to mention with regards to accessing XML files. It appears that you can not use Javascript to access local XML files using XMLHttpRequest, you can only access files found on a domain. I am completely perplexed as to why this is and if anyone out there has knowledge of the reason, or knows a workaround, I'd love to hear from you.
// Ryan Jennings
Labels: crossword, game, how to, iphone development, javascript, xml
MindComet at 8:09 PM - View Post


