XML DOM – Navigating Nodes

The node relationships can be used to navigate through the nodes.

Navigating DOM Nodes:

Navigating nodes simply means accessing the nodes in the node tree via the relationship between nodes. Node relationships are defined as properties to the nodes in the XML DOM.

  • parentNode
  • childNodes
  • firstChild
  • lastChild
  • nextSibling
  • previousSibling

DOM – Parent Node:

There is exactly one parent node for any node.

Books.xml:

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
 
  <book category="Child">
    <title lang="en">ABC</title>
    <author>Unknown</author>
    <year>2020</year>
    <price>100.00</price>
  </book>
 
  <book category="IT">
    <title lang="en">XQuery Book</title>
    <author>Author 1</author>
    <author>Author 2</author>
    <author>Author 3</author>
    <author>Author 4</author>
    <year>2004</year>
    <price>350.00</price>
  </book>
 
</bookstore>

Explanation:

Here, the <bookstore> is the root node in the XML. Within this node, all other nodes in the document are included. There are two <book> nodes in the root node <bookstore>. Each <book> node holds four child nodes: <title>, <author>, <year>, and <price>, while each child node contains one text node each, “ABC”, “Unknown”, “2020”, and “100.00”.

Example:

<!DOCTYPE html>
<html>
<body>
 
<p id="hello"></p>
 
<script>
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        myFunction(this);
    }
};
xhttp.open("GET", "books.xml", true);
xhttp.send();
 
function myFunction(xml) {
    var xmlDoc = xml.responseXML;
    var x = xmlDoc.getElementsByTagName("book")[0];
    document.getElementById("hello").innerHTML = x.parentNode.nodeName;
}
</script>
</body>
</html>

Output:

Explanation:

In the above example, we are navigating to the parent node of <book>. For this, we will first load “books.xml” into xmlDoc to get the first <book> element. We will then output the node name of the parent node of “x”.

Avoid Empty Text Nodes:

The empty white-spaces or newlines are not treated as text nodes by the Internet Explorer, but Firefox and some other browsers do. Thus, while using the properties: firstChild, lastChild, nextSibling, previousSibling, we can face some issues. A function is used to check the node type, in order to avoid navigating to empty text nodes, i.e., spaces and new-line characters between element nodes.

Code:

function get_nextSibling(n) {
    var y = n.nextSibling;
    while (y.nodeType! = 1) {
        y = y.nextSibling;
   }
    return y;
}

Explanation:

Instead of the property node.nextSibling, the get_nextSibling(node) is allowed to be used by the above function. Here, the element nodes are of type 1. Thus, it keeps moving to the next nodes, if the sibling node is not an element node until an element node is found. Thus for both Internet Explorer and Firefox, the result will be the same.

Books.xml:

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
 
  <book category="Child">
    <title lang="en">ABC</title>
    <author>Author Name</author>
    <year>2020</year>
    <price>100.00</price>
  </book>
 
  <book category="IT">
    <title lang="en">XQuery Book</title>
    <author>Author 1</author>
    <author>Author 2</author>
    <author>Author 3</author>
    <author>Author 4</author>
    <year>2004</year>
    <price>350.00</price>
  </book>
 
</bookstore>

Example 1: Get the First Child Element:

<!DOCTYPE html>
<html>
<body>
 
<p id="hello"></p>
 
<script>
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        myFunction(this);
    }
};
xhttp.open("GET", "books.xml", true);
xhttp.send();
 
function myFunction(xml) {
    var xmlDoc = xml.responseXML;
    var x = get_firstChild(xmlDoc.getElementsByTagName("book")[0]);
    document.getElementById("hello").innerHTML = x.nodeName;
}
 
function get_firstChild(n) {
    var y = n.firstChild;
    while (y.nodeType != 1) {
        y = y.nextSibling;
    }
    return y;
}
</script>
 
</body>
</html>

Output:

Explanation:

In the above example, the first element node of the first <book> is displayed. For this, we will first load “books.xml” into xmlDoc and to get the first child node that is an element node we will use the get_firstChild function on the first <book> element node. We will then output the node name of the first child node which is an element node.

Example 2: lastChild():

<!DOCTYPE html>
<html>
<body>
 
<p id="hello"></p>
 
<script>
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        myFunction(this);
    }
};
xhttp.open("GET", "books.xml", true);
xhttp.send();
 
function myFunction(xml) {
    var xmlDoc = xml.responseXML;
    var x = get_lastChild(xmlDoc.getElementsByTagName("book")[0]);
    document.getElementById("hello").innerHTML =
    x.nodeName;
}
 
function get_lastChild(n) {
    var y = n.lastChild;
    while (y.nodeType!=1) {
        y = y.previousSibling;
    }
    return y;
}
</script>
 
</body>
</html>

Output:

Explanation:

In the above example, we are using the lastChild() method and a custom function to get the last child node of a node.

Example 3: nextSibling():

<!DOCTYPE html>
<html>
<body>
 
<p id="hello"></p>
 
<script>
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        myFunction(this);
    }
};
xhttp.open("GET", "books.xml", true);
xhttp.send();
 
function myFunction(xml) {
    var xmlDoc = xml.responseXML;
    var x = get_nextSibling(xmlDoc.getElementsByTagName("author")[0]);
    document.getElementById("hello").innerHTML = x.nodeName;
}
 
function get_nextSibling(n) {
    var y = n.nextSibling;
 
    while (y.nodeType != 1) {
        y = y.nextSibling;
    }
    return y;
}
</script>
 
</body>
</html>

Output:

Explanation:

In the above example, we are using the nextSibling() method and a custom function to get the next sibling node of a node.

Example 4: previousSibling():

<!DOCTYPE html>
<html>
<body>
 
<p id="hello"></p>
 
<script>
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        myFunction(this);
    }
};
xhttp.open("GET", "books.xml", true);
xhttp.send();
 
function myFunction(xml) {
    var xmlDoc = xml.responseXML;
    var x = get_previousSibling(xmlDoc.getElementsByTagName("year")[0]);
    document.getElementById("hello").innerHTML = x.nodeName;
}
 
function get_previousSibling(n) {
    var y = n.previousSibling;
 
    while (y.nodeType != 1) {
        y = y.previousSibling;
    }
    return y;
}
</script>
 
</body>
</html>

Output:

Explanation:

In the above example, we are using the previousSibling() method and a custom function to get the previous sibling node of a node.

Please Share