Lesson 5 of 6

Parsing XML

Once you've got a well-formed XML document, something has to turn that text into data your code can actually work with. There are two fundamentally different ways to do that — one that reads the whole thing into memory as a navigable tree, and one that streams through it event by event without ever holding the whole thing at once. Which one you want depends entirely on how big your document is and what you're trying to do with it.

💡 The Bottom Line

DOM parsing loads an entire XML document into an in-memory tree you can freely navigate and query, at the cost of memory for large documents. Streaming parsing (like SAX) fires events — "start tag," "text," "end tag" — as it reads through the document once, using far less memory but requiring more awkward, stateful code to track where you are.

DOM parsing: load it all, then explore

DOM (Document Object Model) parsing reads the entire document and builds a tree of objects in memory, mirroring the nested element structure exactly. Once it's built, you can walk the tree, search for elements, and read values in any order you like — the whole thing is just sitting there in memory, ready to query.

The tradeoff is memory: a 2GB XML file becomes (roughly) a 2GB+ tree of objects in memory before you can do anything with it. For most everyday documents this is completely fine — it's only a problem once documents get genuinely huge.

A quick DOMParser example

Browsers ship a built-in DOMParser that does exactly this. Here's a small, conceptual example parsing an XML string and reading a value back out of it:

const xmlText = `<book>
  <title>Dune</title>
  <author>Frank Herbert</author>
</book>`;

const parser = new DOMParser();
const doc = parser.parseFromString(xmlText, "application/xml");

const title = doc.querySelector("title").textContent;
console.log(title); // "Dune"

parseFromString builds the whole tree up front; after that, querySelector and friends let you navigate it just like you'd navigate the HTML DOM of a web page — because, structurally, that's exactly what it is.

🙋 There Are No Dumb Questions

Q: How do I know if parsing failed?
A: DOMParser doesn't throw an exception on malformed XML — instead it returns a document containing a <parsererror> element describing what went wrong. Always check for that element if you're parsing XML you don't fully trust.

Streaming (SAX-style) parsing: one pass, no full tree

SAX (Simple API for XML) takes the opposite approach. Instead of building a tree, it reads through the document once and calls your code back with events as it goes — "here's a start tag called book," "here's some text," "here's an end tag called book," and so on. Nothing is held in memory beyond whatever your own code chooses to remember.

🔑 Key Distinction: DOM vs streaming

  • DOM — whole document in memory as a tree; easy, flexible querying; higher memory use; simpler code to write.
  • Streaming / SAX — one pass, event callbacks; minimal memory use even for huge documents; you have to track state yourself (e.g., "am I currently inside a <book> element?"), which makes the code more awkward to write and reason about.

⚠️ Watch Out

Streaming parsing isn't just "the fast option" — it genuinely trades away convenience. If you need to look ahead, look back, or cross-reference different parts of the document, that's trivial with a DOM tree sitting in memory and painful with a one-pass event stream. Reach for streaming specifically when document size makes DOM parsing impractical, not by default.

🔧 Try It Yourself

Open your browser's developer console and paste in the DOMParser example above. Then try doc.querySelectorAll("book") on a document with multiple <book> elements and loop over the results — that's DOM-style navigation in action.

✅ Quick Check

What's the main advantage of streaming (SAX-style) parsing over DOM parsing?


Next up: the common mistakes that break XML documents — unescaped characters, mismatched tags, and the difference between "well-formed" and "valid" that trips up almost everyone at least once.

← Back to
Next →