Skip to content

Parsing documents

Greg Bowler edited this page Apr 18, 2026 · 1 revision

There are three main entry points when working with markup in this library:

  • HTMLDocument for HTML documents
  • XMLDocument for XML documents
  • DOMParser when the incoming content type decides which one to use

HTMLDocument

HTMLDocument is the most common starting point.

use GT\Dom\HTMLDocument;

$document = new HTMLDocument("<h1>Hello</h1>");

The constructor does a few useful things for us:

  • it loads the HTML using PHP's DOM extension
  • it ensures there is a root <html> element
  • it ensures there is a <head>
  • it ensures there is a <body>
  • it preserves non-element child nodes where possible

That means even a small fragment ends up as a proper document tree when serialised.

XMLDocument

For XML, use XMLDocument instead:

use GT\Dom\XMLDocument;

$document = new XMLDocument('<?xml version="1.0"?><feed />');

XMLDocument is useful when we are working with XML semantics rather than HTML semantics. In particular, XML-specific features such as CDATA sections belong here, not in HTMLDocument.

MDN references:

DOMParser

If we receive markup together with a MIME type, DOMParser can choose the right document class:

use GT\Dom\DOMParser;

$parser = new DOMParser();
$document = $parser->parseFromString($markup, "text/html");

Supported content types are effectively HTML and XML families. Unsupported MIME types throw a MimeTypeNotSupportedException.

MDN reference:

Character encoding

HTMLDocument defaults to UTF-8, and the constructor includes a workaround so UTF-8 HTML is parsed and serialised correctly by PHP's DOM layer.

In practice, that means content such as emoji and non-ASCII text can be loaded and emitted without requiring extra manual handling in normal cases.

Document writing and stream behaviour

The Document classes also implement a stream-like interface compatible with PSR-7 style expectations.

$document = new HTMLDocument("<h1>Example</h1>");
$document->open();
$document->write("More text");
echo $document->getContents();

This is mainly useful when a document needs to behave like a stream object in surrounding infrastructure.

A few things are worth knowing:

  • writing is only supported for HTMLDocument
  • calling open() is required before stream writing
  • XML documents are not writable in this way
  • write() appends to the document body rather than acting like a browser runtime parser

If what you need is normal DOM manipulation, the standard node APIs are usually clearer than the stream API.

HTML versus XML: practical advice

  • Use HTMLDocument for webpages, fragments, email markup, generated HTML, and most server-rendered output.
  • Use XMLDocument for feeds, XML configuration, or XML-based interchange formats.
  • Use DOMParser when the caller already gives you the content type and you want a standards-shaped entry point.

Note

In WebEngine, the framework has already loaded the page into an HTMLDocument, so this whole document-construction step is usually skipped.


Next we will look at the parts of the API that are used to navigate around a document: Document traversal.

Clone this wiki locally