Jump to content

XML node accessing/confusion


Don E

Recommended Posts

I've been taking a look at XML and have some confusion. Here's the XML file.. books1.xml:

<?xml version="1.0" encoding="ISO-8859-1"?><bookstore><book> <title>XML</title> <author>John Doe</author></book></bookstore>

And here's the html file:

<!DOCTYPE HTML><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>XML</title><script type="text/javascript">window.onload = function(){if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari  xmlhttp = new XMLHttpRequest(); }else {// code for IE6, IE5  xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.open("GET","books1.xml",false);xmlhttp.send();xmlDoc = xmlhttp.responseXML; book = xmlDoc.getElementsByTagName("book");var y = book[0].childNodes[0];console.log(y.nodeValue);}</script> </head> <body></body></html>

According to what I gathered, console.log should display 'XML' but nothing displays for me, not even errors. book[0] is suppose to get the first book and there's only one anyway. So then book[0] would give me access to the first book listing. Then, isn't y = book[0].childNodes[0]; give me access to first 'title' element? Also, isn't console.log then suppose to display the value for the title element, which is XML? Thanks, any input is really appreciated it.

  • Like 1
Link to comment
Share on other sites

you have to check the readystatechange in ajax in onstatechange callback and the response will be available when it success. send() does not mean it recives the response in the next line. it sends the data and wait for the response. here you are trying to get that what is not set yet,

Link to comment
Share on other sites

I don't think that matters when it comes to accessing xml files or text files in general. I think what you mentioned is really only for server requests, but I could be wrong. Here's an example from w3schools website:This is the HTML page:

<!doctype html><html><head><script type="text/javascript" src="loadxmldoc.js"></script></head><body> <script type="text/javascript"> xmlDoc=loadXMLDoc("books.xml"); x=xmlDoc.getElementsByTagName("title")[0]y=x.childNodes[0];document.write(y.nodeValue); </script></body></html>

This is what the loadxmldoc.js looks like:

function loadXMLDoc(dname){if (window.XMLHttpRequest)  {  xhttp=new XMLHttpRequest();  }else  {  xhttp=new ActiveXObject("Microsoft.XMLHTTP");  }xhttp.open("GET",dname,false);xhttp.send();return xhttp.responseXML;}

This is the xml file:

<bookstore><book category="cooking"><title lang="en">Everyday Italian</title><author>Giada De Laurentiis</author><year>2005</year><price>30.00</price></book><book category="children"><title lang="en">Harry Potter</title><author>J K. Rowling</author><year>2005</year><price>29.99</price></book><book category="web"><title lang="en">XQuery Kick Start</title><author>James McGovern</author><author>Per Bothner</author><author>Kurt Cagle</author><author>James Linn</author><author>Vaidyanathan Nagarajan</author><year>2003</year><price>49.99</price></book><book category="web" cover="paperback"><title lang="en">Learning XML</title><author>Erik T. Ray</author><year>2003</year><price>39.95</price></book></bookstore>

Link to comment
Share on other sites

I don't think that matters when it comes to accessing xml files or text files in general. I think what you mentioned is really only for server requests
Actualy when you access any file it uses request on server. it does not matter the file type. It was my mistake that i did not notice in hurry, you are using syncronized ajax request. Sorry for that. when you synced request it waits till its gets the response from the server. which is not in the case with async. actual problem is... y=x.childNodes[0];it is not pointing the node you are intending. you have \n after your book node. new line is considered a node here, text node.y=x.childNodes[1]; <== it will point it to the title node remember y is pointing to this <title>XML</title>node. "XML" is also considered a node (text node) which is child node of title. so to get its vvalue you haveto get childnodes of title element and then you have to get the node value of itsomething like
book = xmlDoc.getElementsByTagName("book");console.log(book[0].childNodes[1].childNodes[0].nodeValue);

Edited by birbal
Link to comment
Share on other sites

BTW, in all browsers (even IE6!!!), if you have an element node you know contains only text, you can use innerHTML to get the text.e.g.

book = xmlDoc.getElementsByTagName("book");console.log(book[0].childNodes[1].innerHTML);

There are other ways (like innerText, textContent, or even just nodeValue itself), but they work differently in different browsers.Note IE7 and earlier treat childNodes in the way you treated them - they ignore whitespace nodes. If you want to write code compatible with those browsers, the best way to do so is to remove any whitespace nodes, so that your XML looks like:

<?xml version="1.0" encoding="ISO-8859-1"?><bookstore><book><title>XML</title><author>John Doe</author></book></bookstore>

Link to comment
Share on other sites

Thanks Birbal and Boen for your input.So to clarify: When we see something like this:<bookstore> <book> <--- this space right here is considered a childNode of book; so var y = book[0].childNodes[0]; would target this space. To get to title, we have to do this: var y = book[0].childNodes[1]; <title>Learn XML</title> <author>John Doe</author> </book></bookstore>Everything in between element tags ie: <title></title> is considered a chiildNode of this tag, even if it's just plain text?So <title>Learm XML</title>, first child (childNodes[0] in this case) of title is 'Learn XML'. To get that value we would do: childNodes[0].nodeValue; For some reason prior to all this, I was under the impression this was considered the 'nodeValue' because it is plain text and that childNodes[] is only used to get another element within that element, this case being title. So in other words, I was under the impression that to get 'Learn XML', we would just do this: var y = book[0].childNodes[1].nodeValue; but instead it's actually this: var y = book[0].childNodes[1].childNodes[0].nodeValue;

Link to comment
Share on other sites

Yes.

For some reason prior to all this, I was under the impression this was considered the 'nodeValue' because it is plain text and that childNodes[] is only used to get another element within that element, this case being title
Some browsers do just that.This whitespace thing is pretty much the biggest headache people have with DOM, especially in the bad old days when IE differed, and you're thinking "Why is only IE doing the right thing? Arghh!!! This DOM stuff is hard!".
Link to comment
Share on other sites

When it does not work and in doubt you can dump the childNodes in console. so that you will get how does browser geting the nodes.

For some reason prior to all this, I was under the impression this was considered the 'nodeValue' because it is plain text
if you have come from php dom which is also has same specification of DOM,it is usual to think that. php dom produces the text of a node element when you use nodeValue.
Link to comment
Share on other sites

HTML DOM is pretty much like an extension of XML DOM. That means that is has basically everything that XML DOM has and more.

Link to comment
Share on other sites

Hello, This instruction is very dangerous x.childNodes[0]; Because you wait for an element node at the first index therefore it could bea text node and it can depend on the navigator. You may use the getElementsByTagName forfiltering the good one. Best wishes

Edited by japisoft
  • Like 1
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
×
×
  • Create New...