Chapter 40: DOM Get Values
XML DOM – Getting Node Values.
I will explain it as if I am your personal teacher sitting next to you — going slowly, using simple analogies, drawing small trees on the whiteboard, showing many different situations, pointing out traps, explaining why certain properties behave the way they do, and giving you copy-paste-ready code you can test immediately.
1. The most important sentence to remember first
There is no single “get value” method that works the same way for every kind of node.
- For text nodes → you usually want nodeValue or data
- For element nodes → you usually want textContent
- For attribute nodes → you want value or nodeValue
- For document or comment → the value is often null or empty
So the first skill is knowing what kind of node you are holding — because the “value” means something different depending on the node type.
2. The four most common ways people want to “get the value”
| What people usually mean when they say “get the value” | Recommended property / method | Node types where it works best | Returns | Typical example result |
|---|---|---|---|---|
| “Give me all the readable text inside this element and its children” | textContent | Element nodes | string | “Atomic HabitsJames Clear499.00” |
| “Give me the exact text directly inside this node (no descendants)” | nodeValue or data | Text nodes, CDATA, Comment, ProcessingInstruction | string or null | “Atomic Habits” |
| “Give me the value of this attribute” | value (on Attr node) or getAttribute() | Attribute nodes | string | “INR” |
| “Give me the text of the first text child” | firstChild.nodeValue | Element nodes that have direct text | string or null | “Atomic Habits” |
3. Visual example – XML and its nodes
|
0 1 2 3 4 5 6 7 8 9 10 11 |
<book id="B101"> <!-- Popular book --> <title>Atomic Habits</title> <author>James Clear</author> <price currency="INR">499.00</price> </book> |
Let’s label the nodes:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Element: book ├── Attribute: id = "B101" ├── Comment: <!-- Popular book --> ├── Element: title │ └── Text node: "Atomic Habits" ├── Element: author │ └── Text node: "James Clear" └── Element: price ├── Attribute: currency = "INR" └── Text node: "499.00" |
Now let’s see what each property returns for different starting points.
4. Code examples – Getting values from different starting points
|
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 |
// Assume xmlDoc is already parsed // ──────────────────────────────────────────────── // Starting from an ELEMENT node (<price>) const priceElement = xmlDoc.querySelector("price"); // 1. Most common: all text inside (including descendants) console.log("textContent:", priceElement.textContent); // → "499.00" // 2. Only direct text child (usually what you want for simple elements) console.log("direct text:", priceElement.firstChild?.nodeValue?.trim()); // → "499.00" // 3. Attribute value console.log("currency:", priceElement.getAttribute("currency")); // → "INR" // ──────────────────────────────────────────────── // Starting from a TEXT node const titleText = xmlDoc.querySelector("title").firstChild; console.log("nodeValue:", titleText.nodeValue); // "Atomic Habits" console.log("data:", titleText.data); // "Atomic Habits" (same as nodeValue for text) console.log("textContent:", titleText.textContent); // "Atomic Habits" // ──────────────────────────────────────────────── // Starting from an ATTRIBUTE node const attr = xmlDoc.querySelector("price").attributes.getNamedItem("currency"); console.log("attr.nodeValue:", attr.nodeValue); // "INR" console.log("attr.value:", attr.value); // "INR" (same) console.log("attr.name:", attr.name); // "currency" // ──────────────────────────────────────────────── // Starting from COMMENT node const comment = xmlDoc.querySelector("book").firstChild; // assuming comment is first child console.log("comment.nodeValue:", comment.nodeValue); // " Popular book " console.log("comment.textContent:", comment.textContent); // same |
5. The most common real-world patterns
Pattern 1 – Get clean text from an element (recommended most of the time)
|
0 1 2 3 4 5 6 7 8 9 10 11 |
function getCleanText(element) { return element?.textContent?.trim() || ""; } console.log(getCleanText(xmlDoc.querySelector("title"))); // → "Atomic Habits" |
Pattern 2 – Get first direct text child (very common for simple leaf elements)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
function getDirectText(element) { const first = element.firstChild; return first && first.nodeType === 3 ? first.nodeValue.trim() : ""; } console.log(getDirectText(xmlDoc.querySelector("price"))); // → "499.00" |
Pattern 3 – Get attribute safely with fallback
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
function getAttr(element, name, defaultValue = "") { return element?.hasAttribute(name) ? element.getAttribute(name) : defaultValue; } console.log(getAttr(xmlDoc.querySelector("price"), "currency", "USD")); // → "INR" console.log(getAttr(xmlDoc.querySelector("title"), "currency", "USD")); // → "USD" (fallback) |
Pattern 4 – Get text from all matching elements
|
0 1 2 3 4 5 6 7 8 |
const prices = xmlDoc.querySelectorAll("price"); const priceValues = Array.from(prices).map(p => p.textContent.trim()); console.log(priceValues); // ["499.00", ...] |
6. Common beginner mistakes & how to avoid them
Mistake 1 — Using nodeValue on an element node
|
0 1 2 3 4 5 6 |
console.log(priceElement.nodeValue); // null — because elements don't have nodeValue |
Fix: Use textContent or firstChild.nodeValue for elements
Mistake 2 — Forgetting to trim whitespace
|
0 1 2 3 4 5 6 |
console.log(title.firstChild.nodeValue); // may include leading/trailing spaces/newlines |
Fix: always .trim()
Mistake 3 — Assuming every element has exactly one text child
|
0 1 2 3 4 5 6 |
<name>John <middle>Doe</middle> Smith</name> |
→ multiple text nodes + element child
Fix: use textContent when you want all text
Mistake 4 — Using innerHTML on pure XML DOM
|
0 1 2 3 4 5 6 |
console.log(priceElement.innerHTML); // often empty or undefined in strict XML DOM |
Fix: textContent or nodeValue on text nodes
Summary – XML DOM Node Value Quick Reference
| Starting node type | You probably want… | Recommended property | Returns | Notes / Traps |
|---|---|---|---|---|
| Element | All text inside + children | textContent | string | Includes all descendants + whitespace |
| Element | Only direct text | firstChild?.nodeValue?.trim() | string or undefined | May be null if no text or first child is element |
| Text | The text itself | nodeValue or data | string | Same value, data is alias |
| Attribute | The attribute value | value or nodeValue | string | Same value |
| Comment | The comment text | nodeValue or data | string | Usually ignored in output |
| Document | — | — | null | No value |
Would you like to continue with one of these next?
- How to clean & normalize text values (remove extra whitespace, collapse spaces)
- Getting values from namespaced elements (very common in real XML)
- Safely getting numeric / boolean / date values from nodes
- Real-world patterns — extracting price + currency pairs, collecting all titles, etc.
- Debugging when nodeValue / textContent gives unexpected results
- Comparing nodeValue vs textContent vs innerText (differences & pitfalls)
Just tell me which direction you want to explore next! 😊
