0

This php script is able to traverse the nodes of an XML file to show the data in an HTML table. I have been trying to do the same with a javascript but the getElementsbyTagName method hasn't gotten me there yet. What is the problem with the javascript?

PHP script

<?php
// load SimpleXML
$nodes = new SimpleXMLElement('communities.xml', null, true);

echo <<<EOF
<table>
        <tr>
                <th>ID</th>
                <th>Name</th>
                <th>Top</th>
                <th>Left</th>
                <th>Width</th>
                <th>Height</th>
        </tr>

EOF;
foreach($nodes as $node) // loop through our books
{
        echo <<<EOF
        <tr>
                <td>{$node['ID']}</td>
                <td>{$node->NAME}</td>
                <td>{$node->TOP}</td>
                <td>{$node->LEFT}</td>
                <td>{$node->WIDTH}</td>
                <td>{$node->HEIGHT}</td>
        </tr>

EOF;
}echo '</table>';
?>

Javascript

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-

transitional.dtd">

<html lang="en-US" xml:lang="en-US" xmlns="http://www.w3.org/1999/xhtml">
<head>

<script type="text/javascript">
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","communities.xml",false);
xmlhttp.send();
xmlDoc=xmlhttp.responseXML; 

y=xmlDoc.getElementsByTagName("COMMUNITIES")[0].childNodes;

n=y.length;

//document.write("n "+n+"<br/>");

for (i=0;i<n;i++)
{
  document.write(y[i].nodeName);
  att=y.item(i).attributes.getNamedItem("ID");
  document.write(att.value + "<br />");

  x=y.item(i).childNodes;

  name=(y[i].getElementsByTagName("NAME")[0].childNodes[0].nodeValue);
  /* top =(y[i].getElementsByTagName("TOP")[0].childNodes[0].nodeValue);
  left=(y[i].getElementsByTagName("LEFT")[0].childNodes[0].nodeValue);
  width =(y[i].getElementsByTagName("WIDTH")[0].childNodes[0].nodeValue);
  height=(y[i].getElementsByTagName("HEIGHT")[0].childNodes[0].nodeValue); */

  document.write(name+"<br/>");
  /* document.write(top+"<br/>");
  document.write(left+"<br/>");
  document.write(width+"<br/>");
  document.write(height+"<br/>");*/

}


</script>
</head>
<body>

<div id='show'></div>

</body>
</html>

The script only runs if I don't access the node data (top, left, width, height). I commented out the lines where that data was accessed.

XML data

<?xml version="1.0" encoding="ISO-8859-1" ?> 
<COMMUNITIES>
<COMMUNITY ID="c001">
  <NAME>Town Services</NAME> 
  <TOP>50</TOP> 
  <LEFT>50</LEFT> 
  <WIDTH>200</WIDTH> 
  <HEIGHT>300</HEIGHT> 
  <URLS>
      <URL ID="U001">
          <NAME>Google.com</NAME>
          <URL>http://www.google.com</URL>
      </URL>
      <URL ID="U002">
          <NAME>Bing.com</NAME>
          <URL>http://www.bing.com</URL>
      </URL>
      <URL ID="U003">
          <NAME>Yahoo.com</NAME>
          <URL>http://www.yahoo.com</URL>
      </URL>
      <URL ID="U004">
          <NAME>Aol.com</NAME>
          <URL>http://www.aol.com</URL>
      </URL>
  </URLS> 
  </COMMUNITY>
<COMMUNITY ID="c002">
  <NAME>Local Stores</NAME> 
  <TOP>50</TOP> 
  <LEFT>260</LEFT> 
  <WIDTH>200</WIDTH> 
  <HEIGHT>150</HEIGHT> 
  <URLS>
      <URL ID="U001">
          <NAME>Walgreens</NAME>
          <URL>http://www.walgreens.com</URL>
      </URL>
      <URL ID="U002">
          <NAME>Bing.com</NAME>
          <URL>http://www.bing.com</URL>
      </URL>
      <URL ID="U003">
          <NAME>Yahoo.com</NAME>
          <URL>http://www.yahoo.com</URL>
      </URL>
  </URLS> 
  </COMMUNITY>
<COMMUNITY ID="c003">
  <NAME>Attractions</NAME> 
  <TOP>50</TOP> 
  <LEFT>470</LEFT> 
  <WIDTH>200</WIDTH> 
  <HEIGHT>300</HEIGHT> 
  <URLS>
      <URL ID="U001">
          <NAME>Museum</NAME>
          <URL>http://www.mfa.org</URL>
      </URL>
      <URL ID="U002">
          <NAME>Park</NAME>
          <URL>http://www.bing.com</URL>
      </URL>
  </URLS> 
  </COMMUNITY>
<COMMUNITY ID="c004">
  <NAME>Online Stores</NAME> 
  <TOP>370</TOP> 
  <LEFT>50</LEFT> 
  <WIDTH>200</WIDTH> 
  <HEIGHT>150</HEIGHT> 
  <URLS>
      <URL ID="U001">
          <NAME>Amazon.com</NAME>
          <URL>http://www.amazon.com</URL>
      </URL>
      <URL ID="U002">
          <NAME>Target.com</NAME>
          <URL>http://www.target.com</URL>
      </URL>
  </URLS> 
  </COMMUNITY>
<COMMUNITY ID="c005">
  <NAME>Online Forums</NAME> 
  <TOP>370</TOP> 
  <LEFT>300</LEFT> 
  <WIDTH>200</WIDTH> 
  <HEIGHT>200</HEIGHT> 
  <URLS>
      <URL ID="U001">
          <NAME>Technet</NAME>
          <URL>http://www.Microsoft.com</URL>
      </URL>
      <URL ID="U002">
          <NAME>MSDN</NAME>
          <URL>http://www.Microsoft.com</URL>
      </URL>
  </URLS> 
  </COMMUNITY>
<COMMUNITY ID="c006">
  <NAME>Travel</NAME> 
  <TOP>370</TOP> 
  <LEFT>480</LEFT> 
  <WIDTH>200</WIDTH> 
  <HEIGHT>200</HEIGHT> 
  <URLS>
      <URL ID="U001">
          <NAME>Southwest</NAME>
          <URL>http://www.mfa.org</URL>
      </URL>
      <URL ID="U002">
          <NAME>Northwest</NAME>
          <URL>http://www.bing.com</URL>
      </URL>
  </URLS> 
  </COMMUNITY>
</COMMUNITIES>

I just began looking at XML and want to understand how to traverse the nodes in both languages.

Thanks.

3 Answers 3

1

The problem might be with how the browsers implement the DOM specification, Firefox &co. respect the standard specification and include additional textNodes for line breaks, empty spaces and so on, most IE versions deviate from the standard and include just the element nodes you have (what I guess you expected should happen).

I think you can use node.getElementsByTagName('*') to get only the Element child nodes of the current node; More precisely,

y=xmlDoc.getElementsByTagName("COMMUNITIES")[0];
//only true child element nodes of the communities node
elementChildNodes = y.getElementsbyTagName('*');

If this doesn't work try using the children property,

y=xmlDoc.getElementsByTagName("COMMUNITIES")[0].children;

You can go to https://developer.mozilla.org/En/DOM/Element.children for more documentation.

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

3 Comments

I am able to get the children of the COMMUNITIES nodes which are tagged COMMUNITY with y=xmlDoc.getElementsByTagName("COMMUNITIES")[0].childNodes;. The problem is getting the children nodes for each COMMUNITY while in the for loop. These nodes are tagged NAME, TOP, LEFT, WIDTH, HEIGHT. Thanks.
Use the children property, just tested, it works.yy=xmlDoc.getElementsByTagName("COMMUNITIES")[0]; y=yy.children; result: COMMUNITYc001 0 Town Services COMMUNITYc002 1 Local Stores COMMUNITYc003 2 Attractions COMMUNITYc004 3 Online Stores COMMUNITYc005 4 Online Forums COMMUNITYc006 5 Travel
childNodes returns 13 children (includes line-breaks, like I said above); children returns the correct number, 6 COMMUNITY nodes.
0

Whitespaces may also(depending on the UA) be detected as node(textNodes).
Use getElementsByTagName() too to access the nodes instead of childNodes.

Or skip everything except elementNodes:

for (i=0;i<n;i++)
{
   if(y[i].nodeType!==1){continue;}
   //....
}

Comments

0

I gave up trying to do this with Javascript. I made all the XML file updates with PHP. That seemed the right approach anyway to update the files.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.