I am Titus working as a SDET in JScript team. Sometime back I came across a situation where the requirement was to pass a XML file and get a Tree Listing back. The Tree Listing should have all nodes in the file along with proper parent/child relationship as well as a good way to differentiate between nodes with/without values. Let’s call nodes with value as properties. I achieved this by using JScript. In this blog you will learn how to read/parse XML file using Microsoft’s XML DOM and use this to create the Tree Listing. 

Let’s take a sample XML file, say test.xml (can be a URL or a file on your system) to get a clear picture of the kind of Tree Listing required and later we will look at the actual code.


The XML file can be looked as

Root Node, name is BookList, has 2 child nodes

childnode0, name is Book and has two properties,

Prop0: Author has a value Paul

Prop1: Price has a value 10.3

childnode1, name is Book and has three properties

Prop0: Author has a value Joe

Prop1: Price has a value 20.95

Prop2: Title has a value Web 2.0

The Required Tree Listing after parsing test.xml is






List of Child Nodes


List of Child Properties


The ReadXMLFile function in the code listing below returns the Tree Listing as required.

Many a times you know the XML file contents and are interested in the list of only a specific node. Making a call to ReadXMLFile with second argument as the node name gives just such a list.

Referring test.xml, a call to ReadXMLFile(“test.xml”, “Author”) gives a list like

Whereas a call to ReadXMLFile(“test.xml”, “Book”), returns the list like the below one

If you have carefully noticed the Tree listing, cNodes as well as cProps is an Array. so by using the proper index value, one can reach the desired node.

Here goes the actual code:

var NODE_TEXT = 3;
* Builds up xmlNode list on parentXMLNode
* by iterating over each node in childNodesLst
function getXMLNodeList_1(childNodesLst,
    var i;
    var curNode;
    var arrLen
    //traverse nodelist to get nodevalues and all child nodes
    for (i = 0; i < childNodesLst.length; i++) {
        //we will ignore all other node types like
        if (childNodesLst[i].nodeType == NODE_ELEMENT
        || childNodesLst[i].nodeType == NODE_TEXT) {
            if (childNodesLst[i].nodeType == NODE_TEXT) {
                //we got the value of the parent node, populate
                //parent node and return back
                parentXMLNode.nValue = childNodesLst[i].nodeValue;
            //we have a new NODE_ELEMENT node
            curNode = new XMLNode(childNodesLst[i].nodeName, childNodesLst[i].nodeValue);
            if (childNodesLst[i].hasChildNodes) {
                getXMLNodeList_1(childNodesLst[i].childNodes, curNode);
                if (curNode.nValue != null) {
                    //we need to add this as a property to the parent node
                    if (parentXMLNode.cProps == null) {
                        parentXMLNode.cProps = new Array();
                        parentXMLNode.hasCProps = true;
                    arrLen = parentXMLNode.cProps.length;
                    parentXMLNode.cProps[arrLen] = curNode;
                } else {
                    //we need to add this as child node to the parent node
                    if (parentXMLNode.cNodes == null) {
                        parentXMLNode.cNodes = new Array();
                        parentXMLNode.hasCNodes = true;
                    arrLen = parentXMLNode.cNodes.length;
                    parentXMLNode.cNodes[arrLen] = curNode;
            } else {
                //no use of such a node
                //mark currNode as null for GC collection
                curNode = null;
* Generates appropriate XMLNodeList from nodes
* in childNodes
function getXMLNodeList(childNodes)
    var xmlNode = new XMLNode(null, null);
    getXMLNodeList_1(childNodes, xmlNode);
    var xmlNodeList = null;
    if (xmlNode.hasCNodes) {
        xmlNodeList = xmlNode.cNodes;
    } else if (xmlNode.hasCProps) {
        xmlNodeList = xmlNode.cProps;
    return xmlNodeList;
/* XMLNde DataStruct */
functionXMLNode(ndName, ndVal)
    this.nName = ndName; //XMLNode name
    this.nValue = ndVal; //the value(if any) associated with XMLNode
    //As of now only property nodes have associated values
    this.hasCNodes = false; //Bool to mark presense of Child Nodes
    this.cNodes = null; //List of child nodes (of type XMLNode)
    this.hasCProps = false; //Bool to mark presense of Property Nodes
    this.cProps = null; //List of property nodes (of type XMLNode)
/* Exposed Functions */
function ReadXMLFile(fileName, tagName)
    if (arguments.length < 1 || arguments.length > 2)
    return null;
    var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
    //load the file sync'ly
    xmlDoc.async = false
    try {
    } catch(e) {
        //failed to load xml file
        return null;
    //lets get the child nodes
    var childNodes = null;
    if (arguments.length == 2) {
        try {
            childNodes = xmlDoc.getElementsByTagName(tagName);
        } catch(e) {
            return null;
    } else {
        childNodes = xmlDoc.childNodes;
    return (getXMLNodeList(childNodes));
var xmlNodes;
xmlNodes = ReadXMLFile("http://www.noweb.com/test.xml");
//For a file on you system
//xmlNodes = ReadXMLFile ("C:\\My Documents\\test.xml");
//root node name is
var RootNodeName = xmlNodes[0].nName;
xmlNodes = ReadXMLFile("http://www.noweb.com/test.xml", "Book");
var cntBooks = xmlNodes.length;
xmlNodes = ReadXMLFile("http://www.noweb.com/test.xml", "Author");
var authorName = xmlNodes[0].nValue;

Hope you enjoyed the blog!