FrontendPro

122Implement a simplified HTML parser and DOM tree builder

hardAbout 75 minutesCodingparsingtreesstringsbrowsers

Problem

Without DOMParser or innerHTML, implement parseHTML(html), which returns a tree:

  • the root is { type: "root", children };
  • elements are { type: "element", tag, attributes, children } (tag names lower-cased, attributes a plain object);
  • text is { type: "text", value } (with entities decoded).

Also implement toHTML(node), which serialises a tree back to HTML (escaping text and attribute values).

Support:

  • nested elements and text;
  • attributes with double quotes, single quotes, no quotes, and boolean attributes (<input disabled> gives disabled: "");
  • void elements (area, base, br, col, embed, hr, img, input, link, meta, source, track, wbr) and self-closing syntax (<x />);
  • comments (<!-- … -->) and <!doctype> are skipped;
  • entities &amp; &lt; &gt; &quot; &#39; and numeric &#NNN; / &#xHH;;
  • <script> and <style> contents are raw text (no tags parsed inside);
  • error recovery: a closing tag closes the nearest matching open element (implicitly closing anything inside it); stray closing tags are ignored; unclosed elements are closed at the end.

Try it yourself

Write your solution, run it, then submit to check it against the tests.

solution.jsJavaScript

Press Run or ⌘ Enter to execute your code.

Step-by-step

Walk the string with an index. At each position you are reading either text (until the next <), a comment, a doctype, a closing tag or an opening tag. Keep a stack of open elements; its top is where new nodes go.

Unlock the full solution

What's inside

  • Step-by-step
  • Approach
  • Solution
  • Complexity
  • Edge cases
  • Follow-up questions
  • Tests

Includes 2 code listings, 5 edge cases, 4 follow-up questions.

One-time payment by UPI, card or net banking. Launch price.

All 150 answersOne payment, yours forever