Write an XML parser for SlideML
Turn SlideML text into a tree your code can walk: tokens, a stack of open elements, and clear errors for mismatched or unclosed tags.
To the computer, <slide padding="48">…</slide> is just a string. Before we can lay anything out, we need to know which elements there are, what attributes they have, and what's inside what. That's the job of an .
<slide padding="48">
<text bold="true">Title</text>
<row gap="20">
<text>Left</text>
<text>Right</text>
</row>
</slide>- slide { padding: 48 }
- text { bold: true }
- #text "Title"
- row { gap: 20 }
- text {}
- #text "Left"
- text {}
- #text "Right"
Why write our own?
General XML libraries handle namespaces, DTDs and dozens of rules we don't need, and they're strict in ways that reject small slips a model makes. Our parser is about 60 lines, handles exactly what SlideML uses, and gives messages we control.
Step 1: tokens (written for you)
tokenize() walks the text with a regular expression and produces a flat list of pieces: an opening tag with its attributes, a closing tag, or some text. It also decodes &, < and friends, and skips comments.
Under the hood — How does the tokenizer's regular expression work?
It tries several alternatives at each position, in order:
<!--[\s\S]*?-->a comment, skipped<\/\s*([\w-]+)\s*>a closing tag, capturing its name<([\w-]+)(…attributes…)\s*(\/?)>an opening tag, its attributes, and an optional/for self-closing([^<]+)text up to the next tag(<)a lone<, like in "< 12 months", kept as text rather than lost
Step 2: the tree (your part)
You read the tokens one at a time and keep a stack: a list of the elements you're currently inside, with the innermost last. Every new node is added to whatever is on top of the stack.
<slide>rootslideopen: add to root, push<text>rootslidetextopen: add to slide, pushTitlerootslidetexttext: add to text</text>rootslideclose: matches text, pop<box/>rootslideself-closing: add, don't push</slide>rootclose: matches slide, pop
- Text: squash whitespace and add a
#textnode, unless it was only whitespace (the indentation between tags). - Opening tag: add the new node to the parent. Unless it's self-closing, push it, because what follows belongs inside it.
- Closing tag: it must match the element on top. If it doesn't, stop with a clear error. Otherwise pop.
Key takeaways
- Parsing is two steps: split the text into tokens, then build a tree from them.
- A stack tracks which element you're inside: opening tags push, closing tags pop.
- Bad XML should fail with a message that says exactly what's wrong.
Sign in to run the exercise
Reading is free. Writing code here needs an account so we have somewhere to keep your Gemini key and the +35 XP you are about to earn.