Chapter 44: DOM Replace Nodes
XML DOM – Replacing Nodes.
I will explain everything as if I’m your personal teacher sitting next to you — going slowly, drawing small trees on the whiteboard, showing before → after examples, using everyday analogies, warning about every possible trap, and giving you realistic, copy-paste-ready code you can run right away.
1. What does “replacing a node” actually mean?
Replacing = removing one node from the tree and putting a different node in exactly the same place (same parent, same position among siblings).
After replacement:
- The old node is removed from the tree
- The new node takes its exact position
- All references to the old node (if any) remain valid but the node is no longer part of the document
Everyday analogy
Imagine the DOM is a family photo album with pages glued in.
- Each node is one photo
- Replacing a node = tearing out one photo and gluing a new photo in exactly the same spot on the same page
- The album page (parent) still has the same number of photos in the same order — only the content of that position changed
2. The main method you will use 95% of the time
parent.replaceChild(newNode, oldNode)
Syntax:
|
0 1 2 3 4 5 6 |
parentNode.replaceChild(newChild, oldChild); |
Rules you must remember:
- Both newChild and oldChildmust already exist in the DOM (or be created properly)
- oldChildmust be a direct child of parentNode
- newChild can be:
- A node you created with document.createElement()
- A node you moved from somewhere else (it will be removed from its old location automatically)
- After replacement, oldChild is detached — it still exists in memory if you have a variable pointing to it
3. Visual before / after example
Before:
|
0 1 2 3 4 5 6 7 8 9 10 11 |
<library> <book id="101"> <title>Old Book Title</title> <author>Old Author</author> </book> </library> |
We want to replace the entire <title> with a new <title>
After:
|
0 1 2 3 4 5 6 7 8 9 10 11 |
<library> <book id="101"> <title>New Improved Title!</title> <author>Old Author</author> </book> </library> |
4. Full realistic example – Different replacement scenarios
|
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 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>XML DOM – Replacing Nodes (Live Demo)</title> <style> body { font-family: Arial, sans-serif; margin: 40px; line-height: 1.6; } button { padding: 12px 24px; margin: 8px 12px 8px 0; background: #7c3aed; color: white; border: none; border-radius: 6px; cursor: pointer; } button:hover { background: #6d28d9; } pre { background: #f3e8ff; padding: 20px; border-radius: 8px; white-space: pre-wrap; font-size: 15px; } .note { color: #6b7280; font-style: italic; margin: 12px 0; } </style> </head> <body> <h2>XML DOM – Replacing Nodes</h2> <p>Click buttons one by one — watch how the XML changes.</p> <button onclick="resetXML()">1. Reset to original XML</button><br><br> <button onclick="replaceTitle()">2. Replace <title> content</button> <button onclick="replaceWholeBook()">3. Replace entire first <book> with new one</button> <button onclick="replacePriceWithDiscount()">4. Replace <price> with <discount> + old price</button> <button onclick="moveAuthorToEnd()">5. Move <author> to be last child</button> <h3>Current XML after changes:</h3> <pre id="output">Original XML will appear after reset…</pre> <script> let xmlDoc = null; const output = document.getElementById("output"); const originalXML = `<?xml version="1.0" encoding="UTF-8"?> <library> <book id="101"> <title>Atomic Habits</title> <author>James Clear</author> <price currency="INR">499.00</price> </book> <book id="102"> <title>Rich Dad Poor Dad</title> <author>Robert Kiyosaki</author> </book> </library>`; function resetXML() { const parser = new DOMParser(); xmlDoc = parser.parseFromString(originalXML, "application/xml"); if (xmlDoc.querySelector("parsererror")) { output.innerHTML = "XML parsing error!"; return; } showCurrentXML(); } function showCurrentXML() { const serializer = new XMLSerializer(); let xml = serializer.serializeToString(xmlDoc); // Make it more readable xml = xml.replace(/> *</g, '>\n<'); output.textContent = xml; } // ──────────────────────────────────────────────── // 2. Replace only the text of <title> in first book // ──────────────────────────────────────────────── function replaceTitle() { if (!xmlDoc) return resetXML(); const firstTitle = xmlDoc.querySelector("book title"); if (firstTitle) { firstTitle.textContent = "Atomic Habits – Updated Edition 2025"; showCurrentXML(); console.log("Title replaced"); } } // ──────────────────────────────────────────────── // 3. Replace entire first <book> with a new book // ──────────────────────────────────────────────── function replaceWholeBook() { if (!xmlDoc) return resetXML(); const library = xmlDoc.documentElement; const firstBook = xmlDoc.querySelector("book"); if (firstBook) { // Create completely new book element const newBook = xmlDoc.createElement("book"); newBook.setAttribute("id", "BOOK-NEW-001"); const newTitle = xmlDoc.createElement("title"); newTitle.textContent = "The New Book Title"; const newAuthor = xmlDoc.createElement("author"); newAuthor.textContent = "New Author Team"; newBook.appendChild(newTitle); newBook.appendChild(newAuthor); // Replace old book with new one library.replaceChild(newBook, firstBook); showCurrentXML(); console.log("Entire first book replaced"); } } // ──────────────────────────────────────────────── // 4. Replace <price> with <discount> element keeping old price // ──────────────────────────────────────────────── function replacePriceWithDiscount() { if (!xmlDoc) return resetXML(); const price = xmlDoc.querySelector("price"); if (price) { const parent = price.parentElement; // <book> // Create new discount element const discount = xmlDoc.createElement("discount"); discount.setAttribute("type", "seasonal"); discount.textContent = "15% off – was " + price.textContent; // Replace price with discount parent.replaceChild(discount, price); showCurrentXML(); console.log("Price replaced with discount"); } } // ──────────────────────────────────────────────── // 5. Move <author> to be the last child of its parent // ──────────────────────────────────────────────── function moveAuthorToEnd() { if (!xmlDoc) return resetXML(); const author = xmlDoc.querySelector("book author"); if (author) { const parent = author.parentElement; // <book> // Moving = remove from current position and append again parent.removeChild(author); parent.appendChild(author); showCurrentXML(); console.log("Moved author to end of book"); } } // Start with original XML resetXML(); </script> </body> </html> |
Summary – Quick reference for replacing nodes
| Goal | Recommended method | Alternative (classic) | Safety note / best practice |
|---|---|---|---|
| Replace text content | element.textContent = “new value” | element.firstChild.nodeValue = “new” | textContent is safest & most common |
| Replace one element with another | parent.replaceChild(newNode, oldNode) | — | Both must belong to same document |
| Replace attribute value | element.setAttribute(“name”, “new”) | element.name = “new” (for some attrs) | setAttribute always works |
| Move node (cut & paste) | oldParent.removeChild(node) + newParent.appendChild(node) | — | Node is automatically removed from old location |
| Replace while keeping position | parent.replaceChild(new, old) | — | Position is preserved exactly |
Common traps & how to avoid them
Trap 1 — Trying to replace a node without its parent
|
0 1 2 3 4 5 6 |
title.replaceChild(newTitle, oldTitle); // Error – title has no children to replace |
Fix: Always go through the parent
Trap 2 — Using node from different document
|
0 1 2 3 4 5 6 7 |
const newDoc = new DOMParser().parseFromString("<new/>", "application/xml"); parent.replaceChild(newDoc.documentElement, oldNode); // WrongDocumentError |
Fix: Create new nodes with xmlDoc.createElement(), not from another document
Trap 3 — Forgetting that replace removes the old node
|
0 1 2 3 4 5 6 7 |
parent.replaceChild(newNode, oldNode); console.log(oldNode.parentNode); // null – oldNode is detached |
Fix: Keep reference before replacement if you need it later
Would you like to continue with one of these next?
- Replacing nodes while traversing (safe patterns)
- Moving nodes between different parents (cut & paste)
- Replacing attributes in bulk
- Replacing whole subtrees (big sections)
- Real-world patterns — updating prices, replacing old entries, migrating data
- Debugging when replacement fails silently or throws errors
Just tell me which direction you want to explore next! 😊
