Chapter 34: DOM Nodes
XML DOM Nodes, written as if I am your patient teacher sitting next to you — drawing on the whiteboard, showing examples, making comparisons, pointing out common confusion, and giving you plenty of practical code you can try right away.
We will go very slowly and clearly so that you really understand:
- What exactly a “node” is
- The different types of nodes you will meet in XML
- How they are organized in a tree
- How to recognize and work with each type in JavaScript
- Real examples with typical patterns and mistakes
Let’s start from the beginning.
1. What is a “Node” in the XML DOM?
When the browser (or any XML parser) reads your XML document, it does not keep it as one big string. It breaks the document into small pieces called nodes.
A node is the smallest unit the DOM works with.
Think of the XML document as a big Lego house. The DOM is the moment when someone takes the house apart into individual Lego bricks — each brick is a node.
Every single thing in the XML document becomes one of these bricks:
- Every opening tag
- Every closing tag
- Every piece of text
- Every attribute
- Every comment
- Even the spaces between tags (sometimes!)
These bricks (nodes) are then connected together in a tree structure — parents have children, siblings are next to each other, etc.
2. The 7 main types of nodes you will meet in XML DOM
| Node Type Number | Node Type Name | What it represents | Common JavaScript way to check | Real example in XML |
|---|---|---|---|---|
| 1 | Element | Any tag: <book>, <name>, <price>… | node.nodeType === 1 | <book>, <price currency=”INR”> |
| 2 | Attribute | Attributes inside opening tags | node.nodeType === 2 | id=”B101″, currency=”INR” |
| 3 | Text | Plain text content between tags | node.nodeType === 3 | Atomic Habits, 499.00 |
| 4 | CDATASection | Text that should not be parsed as markup | node.nodeType === 4 | <![CDATA[<b>not a tag</b>]]> |
| 7 | ProcessingInstruction | <?xml … ?> or <?php … ?> | node.nodeType === 7 | <?xml version=”1.0″ encoding=”UTF-8″?> |
| 8 | Comment | <!– comment –> | node.nodeType === 8 | <!– this is a note –> |
| 9 | Document | The entire document (the root container) | node.nodeType === 9 | The whole XML document |
The two types you will use 95% of the time:
- Element nodes (type 1)
- Text nodes (type 3)
3. Visual example – Let’s see the nodes in a real XML
Take this small but realistic XML:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?xml version="1.0" encoding="UTF-8"?> <book id="B101" lang="en"> <!-- Classic self-help book --> <title>Atomic Habits</title> <author>James Clear</author> <price currency="INR">499.00</price> <inStock>true</inStock> </book> |
Here is how the DOM sees it (node by node):
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
Document (nodeType 9) └── ProcessingInstruction (nodeType 7): <?xml version="1.0" encoding="UTF-8"?> └── Element: book (nodeType 1) ├── Attribute: id = "B101" (nodeType 2) ├── Attribute: lang = "en" (nodeType 2) ├── Comment (nodeType 8): <!-- Classic self-help book --> ├── Element: title (nodeType 1) │ └── Text (nodeType 3): "Atomic Habits" ├── Element: author (nodeType 1) │ └── Text (nodeType 3): "James Clear" ├── Element: price (nodeType 1) │ ├── Attribute: currency = "INR" (nodeType 2) │ └── Text (nodeType 3): "499.00" └── Element: inStock (nodeType 1) └── Text (nodeType 3): "true" |
4. Practical JavaScript – How to recognize and work with each node type
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
// Assume we already parsed XML into xmlDoc function exploreNodes(node, level = 0) { const indent = " ".repeat(level); // Show node type and name/value let info = ""; switch (node.nodeType) { case 1: // Element info = `Element: <${node.tagName}>`; if (node.hasAttributes()) { info += " attributes: "; for (let attr of node.attributes) { info += `${attr.name}="${attr.value}" `; } } break; case 2: // Attribute info = `Attribute: ${node.name} = "${node.value}"`; break; case 3: // Text const text = node.textContent.trim(); if (text) info = `Text: "{text}"`; break; case 4: // CDATA info = `CDATA: ${node.textContent}`; break; case 7: // Processing Instruction info = `PI: ${node.target} ${node.data}`; break; case 8: // Comment info = `Comment: ${node.textContent}`; break; case 9: // Document info = "Document (root)"; break; default: info = `Other node type: ${node.nodeType}`; } if (info) { console.log(indent + info); } // Recurse through children for (let child of node.childNodes) { exploreNodes(child, level + 1); } } // Usage example const parser = new DOMParser(); const xmlString = `...paste the book XML here...`; const xmlDoc = parser.parseFromString(xmlString, "application/xml"); exploreNodes(xmlDoc); |
You will see output similar to:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Document (root) Processing Instruction: xml version="1.0" encoding="UTF-8" Element: <book> attributes: id="B101" lang="en" Comment: Classic self-help book Element: <title> Text: "Atomic Habits" Element: <author> Text: "James Clear" Element: <price> attributes: currency="INR" Text: "499.00" Element: <inStock> Text: "true" |
5. Common beginner mistakes with nodes
- Forgetting that whitespace creates Text nodes
|
0 1 2 3 4 5 6 7 8 |
<book> <title>Atomic Habits</title> ← there are spaces/newlines here </book> |
→ There are Text nodes containing whitespace between <book> and <title> and after </title>
- Using innerHTML on XML nodes
|
0 1 2 3 4 5 6 |
element.innerHTML = "<b>hello</b>"; // Works in HTML, but in pure XML DOM → often ignored or breaks |
Correct: use textContent or create real elements.
- Assuming all children are elements
|
0 1 2 3 4 5 6 7 8 |
for (let child of parent.childNodes) { child.textContent; // Error if child is a Text node or Comment! } |
Correct way:
|
0 1 2 3 4 5 6 7 8 9 10 |
for (let child of parent.childNodes) { if (child.nodeType === 1) { // only elements console.log(child.tagName); } } |
6. Quick Summary – XML DOM Nodes Cheat Sheet
| Node type | nodeType | How to check | Most common use case | Typical code example |
|---|---|---|---|---|
| Element | 1 | node.nodeType === 1 | Tags, containers | document.querySelector(“book”) |
| Attribute | 2 | node.nodeType === 2 | Reading id, class, currency… | element.getAttribute(“id”) |
| Text | 3 | node.nodeType === 3 | Getting/setting text content | element.textContent = “New value” |
| CDATA | 4 | node.nodeType === 4 | Raw code, HTML snippets inside XML | <![CDATA[<b>not parsed</b>]]> |
| Comment | 8 | node.nodeType === 8 | Developer notes (usually ignored) | <!– todo: update price –> |
| Document | 9 | node.nodeType === 9 | Root of everything | xmlDoc.documentElement |
Would you like to continue with one of these next?
- How to ignore whitespace text nodes (very common need)
- Walking the tree manually (parentNode, firstChild, nextSibling…)
- Creating elements & attributes from scratch
- Handling namespaces in real XML (SOAP, RSS, e-invoice…)
- Common real-world patterns (RSS parsing, SOAP response, config file)
- Debugging tricks when responseXML is null
Just tell me which direction feels most useful for you right now! 😊
