Chapter 45: DOM Create Nodes
XML DOM – Creating Nodes.
I will explain it as if I’m your personal teacher sitting next to you — going 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 “creating nodes” actually mean?
Creating a node = making a new piece (element, text, attribute, comment, CDATA, etc.) that didn’t exist before.
Once created, you usually want to attach it somewhere in the tree (append, insert before/after, replace, etc.).
Key facts you must remember from the first minute:
- All new nodes are created by the document that will own them → document.createElement(), document.createTextNode(), document.createAttribute(), etc. → You cannot create a node using a different document and then move it (you’ll get WrongDocumentError)
- Created nodes are not automatically in the tree → They float in memory until you attach them with appendChild(), insertBefore(), etc.
- You can create standalone nodes, work on them, set attributes, add children, and only attach them at the end
Analogy
Imagine the DOM is a big Lego city already built.
- document.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
- Only when you decide to glue it into the city (attach it to a street/parent) does it become part of the real city
2. The most important creation methods
| What you want to create | Method | Returns | Example line | Most common use case |
|---|---|---|---|---|
| New element | document.createElement(“tagname”) | Element | const book = xmlDoc.createElement(“book”) | Almost everything — books, items, sections |
| New text node | document.createTextNode(“text”) | Text | const txt = xmlDoc.createTextNode(“Hello world”) | Adding readable content inside elements |
| New attribute | document.createAttribute(“name”) | Attr | const attr = xmlDoc.createAttribute(“currency”) | Rare — usually use setAttribute() instead |
| New comment | document.createComment(“text”) | Comment | const note = xmlDoc.createComment(“TODO: update”) | Developer notes (usually ignored) |
| New CDATA section | document.createCDATASection(“text”) | CDATASection | const cdata = xmlDoc.createCDATASection(“<b>raw</b>”) | When you want raw HTML/JS inside XML |
| New processing instruction | document.createProcessingInstruction(target, data) | ProcessingInstruction | const pi = xmlDoc.createProcessingInstruction(“xml”, “version=\”1.0\””) | Rare — usually only at document start |
Modern best practice (2025–2026)
For 99% of cases you only need:
- createElement()
- createTextNode()
- setAttribute() (much easier than createAttribute)
3. Visual before / after – Creating & attaching 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> |
We want to:
- Add a new <author> element
- Add a new <price> element with attribute
- Add a comment before the new author
After
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
<library> <book id="101"> <title>Atomic Habits</title> <!-- Added by JavaScript --> <author>James Clear</author> <price currency="INR">499.00</price> </book> </library> |
4. Complete working example – Creating 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 205 206 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>XML DOM – Creating Nodes</title> <style> body { font-family: Arial, sans-serif; margin: 40px; line-height: 1.6; } 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; } </style> </head> <body> <h2>XML DOM – Creating & Adding Nodes</h2> <p>Click buttons one by one — watch the XML grow.</p> <button onclick="resetXML()">1. Reset to original XML</button><br><br> <button onclick="addAuthor()">2. Add <author> element</button> <button onclick="addPriceWithAttribute()">3. Add <price> with currency attribute</button> <button onclick="addComment()">4. Add comment before author</button> <button onclick="addNewBook()">5. Add completely new <book> at the end</button> <button onclick="addDiscountBeforePrice()">6. Insert <discount> before price</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> <price currency="INR">499.00</price> </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); xml = xml.replace(/> *</g, '>\n<'); // make it readable output.textContent = xml; } // ──────────────────────────────────────────────── // 2. Add new <author> element as last child of first book // ──────────────────────────────────────────────── function addAuthor() { if (!xmlDoc) return resetXML(); const firstBook = xmlDoc.querySelector("book"); // Create the 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 firstBook.appendChild(author); showCurrentXML(); console.log("Added new <author> element"); } // ──────────────────────────────────────────────── // 3. Add <price> with attribute (if missing) // ──────────────────────────────────────────────── function addPriceWithAttribute() { if (!xmlDoc) return resetXML(); const firstBook = xmlDoc.querySelector("book"); // Check if price already exists if (firstBook.querySelector("price")) { alert("Price already exists — nothing added"); return; } const price = xmlDoc.createElement("price"); price.textContent = "499.00"; // Set attribute price.setAttribute("currency", "INR"); firstBook.appendChild(price); showCurrentXML(); console.log("Added <price> with currency attribute"); } // ──────────────────────────────────────────────── // 4. Add comment before <author> // ──────────────────────────────────────────────── function addComment() { if (!xmlDoc) return resetXML(); const author = xmlDoc.querySelector("author"); if (!author) { alert("No author yet — add author first"); return; } const comment = xmlDoc.createComment(" Added by JavaScript on " + new Date().toLocaleString()); author.parentNode.insertBefore(comment, author); showCurrentXML(); console.log("Added comment before author"); } // ──────────────────────────────────────────────── // 5. Add completely new <book> at the end of <library> // ──────────────────────────────────────────────── function addNewBook() { 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 JS"; const author = xmlDoc.createElement("author"); author.textContent = "AI Author"; newBook.appendChild(title); newBook.appendChild(author); library.appendChild(newBook); showCurrentXML(); console.log("Added completely new book"); } // ──────────────────────────────────────────────── // 6. Insert <discount> before <price> in first book // ──────────────────────────────────────────────── function addDiscountBeforePrice() { 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"); } // Start with original resetXML(); </script> </body> </html> |
Summary – Quick reference for creating nodes
| What you want to create | Method | Then attach with… | Most common pattern |
|---|---|---|---|
| New element | doc.createElement(“discount”) | parent.appendChild() or insertBefore() | Create → set text → set attributes → attach |
| New text content | doc.createTextNode(“text”) | element.appendChild() | Usually use element.textContent = “…” instead |
| New attribute | element.setAttribute(“name”, “value”) | — (no need to attach) | Almost always use setAttribute |
| New comment | doc.createComment(“note”) | parent.insertBefore() | Rare — mostly for documentation |
| New CDATA section | doc.createCDATASection(“raw text”) | parent.appendChild() | When you want raw HTML/JS inside XML |
Would you like to continue with one of these next?
- Inserting at specific positions (before/after certain nodes)
- Creating nodes from scratch and building whole subtrees
- Moving 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! 😊
