4

I have been trying to find an example on how to go about parsing the following XML document. The sample below shows how much depth I am looking at.

I think I need the following:

1. A function to load the XML.

$.get('getProfile.xml', null, function (data) { // ... }, 'xml'); 

2. A way to loop through root node looking for child nodes. For each child node found, loop through found child node's children looking for new children of children. If none found, just simply output what's inside this child node.

<?xml version="1.0" encoding="utf-8"?> <GetProfile> <UserInfo> <id>free2rhyme</id> <name>jerry mcguire</name> <age>29</age> <sex>m</sex> <location>salt lake city, utah</location> <signup>00/00/0000</signup> </UserInfo> <Entry> <id>13579</id> <date>2011-01-24</date> <time>9:34:21</time> <title>my first jounal entry</title> <body>&lt;![CDATA[i'm really excited to have signed up for myjournal.co.cc! Yes!!!]]&gt;</body> <Comments> <Comment> <id>97531</id> <date>2011-02-16</date> <time>9:34:21</time> <from>otheruser84</from> <body>I am glad you really liked the site! Have fun!!</body> </Comment> <Comment> <id>97531</id> <date>2011-02-16</date> <time>9:34:21</time> <from>otheruser84</from> <body>I am glad you really liked the site! Have fun!!</body> </Comment> <Comment> <id>97531</id> <date>2011-02-16</date> <time>9:34:21</time> <from>otheruser84</from> <body>I am glad you really liked the site! Have fun!!</body> </Comment> </Comments> </Entry> <Stats> <following>40</following> <followers>57</followers> <entries>158</entries> <favorites>15</favorites> </Stats> <Preview> <Entries> <Entry> <id>97531</id> <date>2011-02-16</date> <time>9:34:21</time> <title>otheruser84</title> </Entry> <Entry> <id>97531</id> <date>2011-02-16</date> <time>9:34:21</time> <title>otheruser84</title> </Entry> <Entry> <id>97531</id> <date>2011-02-16</date> <time>9:34:21</time> <title>otheruser84</title> </Entry> <Entry> <id>97531</id> <date>2011-02-16</date> <time>9:34:21</time> <title>otheruser84</title> </Entry> <Entry> <id>97531</id> <date>2011-02-16</date> <time>9:34:21</time> <title>otheruser84</title> </Entry> </Entries> </Preview> </GetProfile> 

3. The sample above hopefully clarifies what I am trying to do.

4. Here's a way to return the node's index, name and value however it does not check for child nodes that may also have children of their own.

var getProfile = $(data).find('GetProfile').each(function () { $('*', this).each(function (index, event) { alert('index=' + index + ' name=' + e.tagName + ' value=' + $(e).text()); }); }); 
4
  • if you are not sending data to server then you don't need to pass NULL in second parameter. Just omit it. Commented Oct 17, 2011 at 13:52
  • I'm not at all clear on what you're trying to do. Can you add an example of the expected output given the sample input? Commented Oct 17, 2011 at 13:56
  • for now I just want to build a <ul> <li> structure of it. I'll make it look pretty later. Commented Oct 17, 2011 at 14:11
  • The latest edit I made to the original post includes a way to get the nodes by index which would keep me from editing the code should an update come up. Commented Oct 17, 2011 at 14:14

2 Answers 2

3

This page provides a snippet to recursively traverse an XML DOM:

function traverse(tree) { if (tree.hasChildNodes()) { document.write('<ul><li>'); document.write('<b>' + tree.tagName + ' : </b>'); var nodes = tree.childNodes.length; for (var i = 0; i < tree.childNodes.length; i++) traverse(tree.childNodes(i)); document.write('</li></ul>'); } else document.write(tree.text); } 

Another way is to use a DOM parser (e.g. window.DOMParser or ActiveXObject("Microsoft.XMLDOM")) to parse an XML string:

if (window.DOMParser) { parser = new DOMParser(); xmlDoc = parser.parseFromString(text, "text/xml"); } else { // Internet Explorer xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); xmlDoc.async = "false"; xmlDoc.loadXML(text); } 

See this page: http://www.w3schools.com/dom/dom_parser.asp.


Edit:

function traverse(tree) { $(tree).contents().each(function() { if (this.nodeType == 3) { // text node // node value: $(this).text() or this.nodeValue console.log('text node value: '+ $(this).text()); } else { console.log('tag name: ' + this.nodeName); traverse(this); } }); } 

See this in action: http://jsfiddle.net/william/uKGHJ/1/.

Sign up to request clarification or add additional context in comments.

7 Comments

Old school sample. I'm using JQuery. Yes I could adapt but that is also the question. I'm not really sure how. =)
You can easily modify the first snippet to do what you want, using some of the traversing methods in jQuery... (api.jquery.com/category/traversing).
Thank you. It seems I can only return the first root node using contents(). If I use children() I can return all nodes but only tag names. Any ideas?
It could be a small bug: this.text(). I updated the answer and included a link to jsfiddle.
instead of using this.nodeType == 3, I think it would be nicer to use this.nodeType == Node.TEXT_NODE, see Node.nodeType.
|
0

you can use something like this .

$(xml).find("Entry").each(function () { alert($(this).find("id").text()) $(this).find("Comments").each(function () { $(this).find("Comment").each(function () { alert($(this).find("id").text()) alert($(this).find("date").text()) alert($(this).find("time").text()) }); }); }); 

1 Comment

This is a cool example. I just wanted to make it so that the code looks for children of children while not necessarily knowing their names in advance.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.