Chapter 46: DOM Add Nodes
XML DOM – Adding Nodes (also called “inserting” or “appending” new nodes).
I will explain everything as if I am your personal teacher sitting next to you — going very slowly, using simple analogies, drawing small trees on the whiteboard, showing before → after examples, warning about every possible trap, and giving you realistic, copy-paste-ready code you can run right now.
1. What does “adding nodes” actually mean?
Adding a node = creating a new node (element, text, attribute, comment, etc.) and attaching it to an existing place in the DOM tree.
The new node becomes part of the document and is visible when you serialize or display the XML.
Key facts you must remember from the very first second:
- All new nodes are created by the same document that owns the tree → always use xmlDoc.createElement(), xmlDoc.createTextNode(), etc. → Never create nodes from a different document and try to insert them (you’ll get WrongDocumentError)
- Creating a node does not automatically put it into the tree → You must explicitly attach it using one of the insertion methods
- You can create → prepare → set attributes → add children → and only then attach it to the tree
Everyday analogy
Imagine the DOM is a big Lego city already built.
- createElement(“house”) = you just bought a new Lego house kit
- You can paint it, add windows, put furniture inside while it’s still in your hands (in memory)
- Only when you decide to glue it to a street (attach to a parent) does it become part of the city
2. The four main ways to attach a new node
| Method | Syntax example | Where the new node ends up | When to use it | Live effect |
|---|---|---|---|---|
| parent.appendChild(newNode) | parent.appendChild(newElement) | As the last child of parent | Most common – add at the end | Immediate |
| parent.insertBefore(newNode, referenceNode) | parent.insertBefore(new, existingChild) | Before the reference node | Insert at specific position (before something) | Immediate |
| parent.insertAdjacentElement() | existing.insertAdjacentElement(“beforebegin”, new) | Before / after / inside existing element | Modern, very readable (2014+) | Immediate |
| parent.prepend(newNode) | parent.prepend(newElement) | As the first child of parent | Add at the beginning (ES2018+) | Immediate |
Modern recommendation (2025–2026)
Use appendChild() and insertBefore() for almost everything — they are the classic, most compatible, and safest methods. Use prepend() / append() / before() / after() only when you want very readable code and don’t care about older browsers.
3. Visual before / after – Adding different kinds of nodes
Before (original XML)
|
0 1 2 3 4 5 6 7 8 9 10 |
<library> <book id="101"> <title>Atomic Habits</title> </book> </library> |
After adding various nodes:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<library> <!-- New comment added at the beginning --> <book id="101"> <title>Atomic Habits</title> <author>James Clear</author> <!-- added at the end --> <discount type="welcome">10% off</discount> <!-- inserted before price --> <price currency="INR">499.00</price> </book> <book id="NEW-999"> <!-- completely new book added at the end --> <title>New Book</title> </book> </library> |
4. Complete working example – Creating & adding different kinds of nodes
|
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 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>XML DOM – Creating & Adding Nodes</title> <style> body { font-family: Arial, sans-serif; margin: 40px; line-height: 1.6; background: #f9fafb; } button { padding: 12px 24px; margin: 8px 12px 8px 0; background: #8b5cf6; color: white; border: none; border-radius: 6px; cursor: pointer; } button:hover { background: #7c3aed; } pre { background: #f3e8ff; padding: 20px; border-radius: 8px; white-space: pre-wrap; font-size: 15px; max-height: 400px; overflow-y: auto; } </style> </head> <body> <h2>XML DOM – Creating & Adding Nodes (Live Demo)</h2> <p>Click the buttons one by one — watch how the XML grows.</p> <button onclick="resetXML()">1. Reset to original XML</button><br><br> <button onclick="addAuthorAtEnd()">2. Add <author> at the end of first book</button> <button onclick="addCommentAtBeginning()">3. Add comment before first book</button> <button onclick="insertDiscountBeforePrice()">4. Insert <discount> before price</button> <button onclick="addNewBookAtEnd()">5. Add completely new <book> at the end of library</button> <button onclick="addPriceWithAttribute()">6. Add <price> with currency attribute</button> <h3>Current XML structure:</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> </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. Add new <author> as last child of first book // ──────────────────────────────────────────────── function addAuthorAtEnd() { if (!xmlDoc) return resetXML(); const firstBook = xmlDoc.querySelector("book"); // Create new element const author = xmlDoc.createElement("author"); // Create text node and attach it const text = xmlDoc.createTextNode("James Clear"); author.appendChild(text); // Attach to the book (as last child) firstBook.appendChild(author); showCurrentXML(); console.log("Added <author> at the end"); } // ──────────────────────────────────────────────── // 3. Add comment as first child of <library> // ──────────────────────────────────────────────── function addCommentAtBeginning() { if (!xmlDoc) return resetXML(); const library = xmlDoc.documentElement; const comment = xmlDoc.createComment(" Added by JavaScript on " + new Date().toLocaleString()); // Insert before the first book const firstBook = library.firstElementChild; library.insertBefore(comment, firstBook); showCurrentXML(); console.log("Added comment at the beginning"); } // ──────────────────────────────────────────────── // 4. Insert <discount> before <price> in first book // ──────────────────────────────────────────────── function insertDiscountBeforePrice() { if (!xmlDoc) return resetXML(); const price = xmlDoc.querySelector("price"); if (!price) { alert("No <price> element found"); return; } const discount = xmlDoc.createElement("discount"); discount.setAttribute("type", "welcome"); discount.textContent = "10% off for new customers"; price.parentNode.insertBefore(discount, price); showCurrentXML(); console.log("Inserted <discount> before price"); } // ──────────────────────────────────────────────── // 5. Add completely new <book> at the end of <library> // ──────────────────────────────────────────────── function addNewBookAtEnd() { if (!xmlDoc) return resetXML(); const library = xmlDoc.documentElement; const newBook = xmlDoc.createElement("book"); newBook.setAttribute("id", "B999"); newBook.setAttribute("lang", "en"); const title = xmlDoc.createElement("title"); title.textContent = "New Book Added via JavaScript"; const author = xmlDoc.createElement("author"); author.textContent = "AI Assistant"; newBook.appendChild(title); newBook.appendChild(author); library.appendChild(newBook); showCurrentXML(); console.log("Added new book at the end"); } // ──────────────────────────────────────────────── // 6. Add <price> with attribute (if missing) // ──────────────────────────────────────────────── function addPriceWithAttribute() { if (!xmlDoc) return resetXML(); const firstBook = xmlDoc.querySelector("book"); if (firstBook.querySelector("price")) { alert("Price already exists — nothing added"); return; } const price = xmlDoc.createElement("price"); price.textContent = "499.00"; price.setAttribute("currency", "INR"); firstBook.appendChild(price); showCurrentXML(); console.log("Added <price> with currency attribute"); } // Start with original XML resetXML(); </script> </body> </html> |
Summary – Quick reference for creating & adding nodes
| Goal | Creation method | Attachment method | Best practice / tip |
|---|---|---|---|
| Create new element | doc.createElement(“discount”) | parent.appendChild() | Most common — create → set text/attributes → attach |
| Create text content | doc.createTextNode(“text”) | element.appendChild() | Usually easier to use element.textContent = “…” |
| Create attribute | element.setAttribute(“name”, “value”) | — (no need to attach) | Almost always use setAttribute instead of createAttribute |
| Create comment | doc.createComment(“note”) | parent.insertBefore() | Usually for developer notes |
| Create CDATA section | doc.createCDATASection(“raw text”) | parent.appendChild() | When you need to include raw HTML/JS inside XML |
| Insert before specific child | — | parent.insertBefore(new, referenceChild) | Very useful for maintaining order |
| Insert at beginning | — | parent.prepend(new) or insertBefore(new, parent.firstChild) | Modern prepend() is very readable |
Would you like to continue with one of these next?
- Inserting at very specific positions (before/after certain nodes, at index)
- Creating complex subtrees (whole book with many children at once)
- Moving existing nodes (cut from one place → paste in another)
- Replacing while creating (create new → replace old)
- Real-world patterns — adding new products, adding metadata, building dynamic catalogs
- Debugging when new nodes “don’t appear” or XML becomes invalid
Just tell me which direction you want to explore next! 😊
