SitePoint Sponsor

User Tag List

Results 1 to 4 of 4
  1. #1
    SitePoint Evangelist NokX's Avatar
    Join Date
    Feb 2003
    Location
    Knoxville, TN
    Posts
    523
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Recursive function to loop through XML/DOM

    i'm trying to write a function that will loop through XML/DOM and store all the node names, values (if any) and attributes (if any) into a javascript object.

    here's my very basic XML file...
    Code:
    <?xml version="1.0" encoding="iso-8859-1"?>
    <data>
        <people>
            <person firstname="Bob" lastname="Jones">
                <email>bobjones@aol.com</email>
                <mobile>865-555-5555</mobile>
            </person>
            <person firstname="Larry" lastname="Smith">
                <email>larrysmith@yahoo.com</email>
                <mobile>865-444-4444</mobile>
            </person>
            <person firstname="Wanda" lastname="Williams">
                <email>wandawilliams@hotmail.com</email>
                <mobile>865-333-333</mobile>
            </person>
        </people>
        <computers>
            <computer brand="Apple">
                <model>MacBook</model>
                <year>2007</year>
            </computer>
            <computer brand="Sony">
                <model>VAIO</model>
                <year>2007</year>
            </computer>
        </computers>
    </data>
    i'm passing along the XML document via AJAX (var doc = req.responseXML.documentElement).

    i can step through the nodes, but not dynamically, which is what i want to do since i'm going to be manipulating multiple XML documents.

    for example, this will output the first couple of levels. real basic, but not dynamic. if i had an XML file with 20 levels i'd have to make one long for() loop.
    Code:
        var result = doc.nodeName;
        for (var i = 0; i < doc.childNodes.length; i++) {
            if (doc.childNodes[i].nodeType == 1) {
                result += "\n\t" + doc.childNodes[i].nodeName;
                for (var j = 0; j < doc.childNodes[i].childNodes.length; j++) {
                    if (doc.childNodes[i].childNodes[j].nodeType == 1) {
                        result += "\n\t\t" + doc.childNodes[i].childNodes[j].nodeName + " (" + doc.childNodes[i].childNodes[j].childNodes.length + ")";
                    }
                }
            }
        }
        alert(result);
    how can i dynamically step through the document object?

  2. #2
    SitePoint Evangelist NokX's Avatar
    Join Date
    Feb 2003
    Location
    Knoxville, TN
    Posts
    523
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    if the above stuff was at all confusing, basically i want to convert an XML document into a javascript object so this...

    xml
    Code:
    <foo>
         <bar>oh noes!</bar>
    </foo>
    becomes this...

    javascript object
    Code:
    var contents_of_bar = foo.bar;

  3. #3
    SitePoint Zealot the DtTvB's Avatar
    Join Date
    Jul 2006
    Location
    Thailand
    Posts
    162
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hope this helps...

    Code JavaScript:
    //
    //  This function converts an XML to JS objects and arrays.
    //
    function convertXmlToStructure(x) {
     
    	//
    	//  Output function.
    	//
    	var o = {
    		_text: '',
    	};
     
    	//
    	//  c = each child
    	//
    	var c = x.firstChild;
     
    	//
    	//  Loop through child nodes.
    	//
    	while (c) {
     
    		//
    		//  Add to _text property if it is a text.
    		//
    		if (c.nodeName == '#text') {
    			o._text += c.nodeValue;
     
    		//
    		//  Else if it is a normal node.
    		//
    		} else if (c.nodeType == 1) {
     
    			//
    			//  Create property for each node name.
    			//
    			if (typeof o[c.nodeName] == 'undefined')
    				o[c.nodeName] = [];
    			o[c.nodeName][o[c.nodeName].length] = convertXmlToStructure(c);
     
    		}
     
    		//
    		//  ...Next!
    		//
    		c = c.nextSibling;
     
    	}
     
    	//
    	//  Now, attributes!
    	//
    	var a = x.attributes;
    	var i = 0;
    	if (a) {
    		for (var i = 0; i < a.length; i ++) {
    			o[a[i].name] = a[i].value;
    		}
    	}
     
    	//
    	//  Clean the text
    	//
    	if (o._text.match(/^\s*$/))
    		delete o._text;
     
    	//
    	//  Finished!
    	//
    	return o;
     
    }


    Example Code:

    Code JavaScript:
    	var xml  = xh.responseXML;
    	var xmls = convertXmlToStructure(xml);
    	var out  = '';
    	var i;
     
    	var people = xmls.data[0].people[0].person;
    	for (i = 0; i < people.length; i ++) {
    		out += people[i].firstname + ' ' + people[i].lastname + '\n -> Email: ' + people[i].email[0]._text + '\n -> Mobile: ' + people[i].mobile[0]._text + '\n';
    	}
     
    	alert (out);

    So for your example, that oh noes file, when you use my convertXmlToStructure function, you can refer to its value like this:

    xmls.foo[0].bar[0]._text

    Where xmls is a parsed JavaScript object.

  4. #4
    SitePoint Evangelist NokX's Avatar
    Join Date
    Feb 2003
    Location
    Knoxville, TN
    Posts
    523
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    that works well! thank you very much.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •