Question

How to Parse and Process HTML/XML in PHP

phphtmlxmlxml-parsinghtml-parsing

Question

How can HTML or XML be parsed in PHP so that information can be extracted from it efficiently and reliably?

For example, how do you load a document, find specific elements or attributes, and read their values using PHP's built-in tools?

Short Answer

By the end of this page, you will understand the main ways to parse HTML and XML in PHP, when to use DOMDocument, DOMXPath, and SimpleXML, and how to extract text, attributes, and elements from structured markup.

Concept

Parsing HTML or XML means turning raw markup text into a structure that your PHP code can navigate.

Instead of searching with fragile string operations like strpos() or regular expressions, a parser understands the document as elements, attributes, text nodes, and hierarchy.

In PHP, the most common built-in tools are:

  • DOMDocument for loading and traversing HTML or XML as a tree
  • DOMXPath for querying that tree with XPath expressions
  • SimpleXML for simpler XML reading when the structure is clean and predictable

Why this matters:

  • HTML and XML are nested formats, so structure matters
  • Manual string parsing breaks easily when formatting changes
  • Parsers let you safely access tags, attributes, and text
  • XPath makes complex searches much easier

A common beginner mistake is trying to parse HTML with regular expressions. That usually fails because HTML is not just plain text—it is a nested document format with optional whitespace, attributes, child elements, and inconsistent formatting.

HTML vs XML in PHP

Although they look similar, PHP usually handles them slightly differently:

  • HTML is often imperfect and forgiving
  • XML must be well-formed

That means:

  • Use DOMDocument::loadHTML() for HTML
  • Use DOMDocument::loadXML() or simplexml_load_string() for XML

If you need flexible searching in either format, XPath is one of the most useful tools.

Mental Model

Think of an HTML or XML document like a family tree.

  • Each tag is a person
  • Parent tags contain child tags
  • Attributes are like labels attached to each person
  • Text inside a tag is that person's content

Parsing means building that family tree in memory.

Once the tree exists, you can:

  • go to a specific branch
  • find all children with a certain name
  • read labels such as id, class, or href
  • collect text from matching nodes

Without parsing, you are guessing by searching raw text. With parsing, you are navigating a real structure.

Take Quiz

Syntax and Examples

Using DOMDocument for HTML

<?php
$html = '<div><a href="/post/1">Read more</a></div>';

$dom = new DOMDocument();
libxml_use_internal_errors(true); // suppress warnings for imperfect HTML
$dom->loadHTML($html);
libxml_clear_errors();

$links = $dom->getElementsByTagName('a');

foreach ($links as $link) {
    echo $link->getAttribute('href') . PHP_EOL;
    echo $link->textContent . PHP_EOL;
}

This example:

  • loads an HTML string
  • finds all <a> elements
  • reads each link's href attribute
  • reads the visible text inside the link

Using DOMXPath for more precise queries

<?php
$html = '
<ul>
    <li class="item">Apple</li>
    <li class="item">Banana</li>
    <li>Orange</li>
</ul>';

$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML($html);
libxml_clear_errors();

$xpath = new DOMXPath($dom);
$nodes = $xpath->query('//li[@class="item"]');

foreach ($nodes as $node) {
    echo $node->textContent . PHP_EOL;
}

This finds only <li> elements whose class attribute is item.

Using SimpleXML for XML

<?php
$xml = '
<books>
    <book id="1">
        <title>Clean Code</title>
        <author>Robert C. Martin</author>
    </book>
    <book id="2">
        <title>Refactoring</title>
        <author>Martin Fowler</author>
    </book>
</books>';

$data = simplexml_load_string($xml);

foreach ($data->book as $book) {
    echo (string) $book['id'] . PHP_EOL;
    echo (string) $book->title . PHP_EOL;
    echo (string) $book->author . PHP_EOL;
}

SimpleXML is great when:

  • the input is valid XML
  • the structure is straightforward
  • you want simple property-style access

Step by Step Execution

<?php
$html = '<div><p class="name">Alice</p></div>';

$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML($html);
libxml_clear_errors();

$paragraphs = $dom->getElementsByTagName('p');
$firstParagraph = $paragraphs->item(0);

echo $firstParagraph->getAttribute('class') . PHP_EOL;
echo $firstParagraph->textContent . PHP_EOL;

Step by step:

  1. $html stores the raw HTML string.
  2. $dom = new DOMDocument(); creates a parser object.
  3. libxml_use_internal_errors(true); tells PHP not to print parser warnings directly.
  4. $dom->loadHTML($html); parses the HTML and builds a document tree.
  5. libxml_clear_errors(); clears any stored parsing warnings.
  6. $dom->getElementsByTagName('p') returns all <p> elements.
  7. item(0) gets the first matching paragraph.
  8. getAttribute('class') reads the class value, which is name.
  9. textContent reads the text inside the paragraph, which is Alice.

Output:

name
Alice

Real World Use Cases

Parsing HTML and XML in PHP is useful in many everyday tasks:

  • Web scraping: extract titles, links, prices, or metadata from HTML pages
  • API integrations: read XML responses from older web services or feeds
  • RSS/Atom feed processing: collect article titles, links, and publish dates
  • Import tools: load product catalogs, invoices, or configuration files in XML format
  • Content migration: extract data from old CMS-generated HTML
  • Server-side validation: inspect generated HTML in tests or processing pipelines

Example scenarios:

  • A script reads an RSS feed and stores article titles in a database
  • An admin tool imports XML product data from a supplier
  • A crawler extracts all links from a page for indexing
  • A test script checks whether generated HTML contains expected elements
Take Quiz

Real Codebase Usage

In real projects, developers usually combine parsing with a few common patterns.

Validation before processing

Check whether parsing succeeded before using the result.

<?php
$xml = '<user><name>Sam</name></user>';
$data = simplexml_load_string($xml);

if ($data === false) {
    echo 'Invalid XML';
    return;
}

echo (string) $data->name;

Guard clauses for missing nodes

<?php
$linkNode = $dom->getElementsByTagName('a')->item(0);

if ($linkNode === null) {
    return;
}

echo $linkNode->getAttribute('href');

Extracting arrays of values

<?php
$items = [];
$nodes = $xpath->query('//a');

foreach ($nodes as $node) {
    $items[] = [
        'text' => trim($node->textContent),
        'href' => $node->getAttribute('href'),
    ];
}

Filtering incomplete data

<?php
$result = [];

foreach ($nodes as $node) {
    $href = $node->getAttribute('href');

    if ($href === '') {
        continue;
    }

    $result[] = $href;
}

Common project pattern

A real codebase often follows this flow:

  1. Load raw HTML or XML
  2. Parse it into a document object
  3. Query for needed nodes
  4. Validate missing or malformed values
  5. Convert results into arrays or objects
  6. Save or return the processed data

Common Mistakes

1. Using regular expressions to parse HTML

Broken approach:

<?php
preg_match('/<a href="(.*?)">(.*?)<\/a>/', $html, $matches);

Why it is a problem:

  • breaks on nested tags
  • breaks on single quotes or different spacing
  • fails when the HTML structure changes

Use DOMDocument instead.

2. Forgetting that HTML and XML use different loaders

Broken approach:

<?php
$dom = new DOMDocument();
$dom->loadXML('<div><p>Hello</p></div>');

This is not valid XML unless it is properly formed as XML and follows XML rules.

Use:

  • loadHTML() for HTML
  • loadXML() for real XML

3. Not checking for missing nodes

Broken code:

<?php
$title = $dom->getElementsByTagName('title')->item(0);
echo $title->textContent;

If no <title> exists, item(0) returns null.

Safer version:

<?php
$title = $dom->getElementsByTagName('title')->item(0);

if ($title !== null) {
    echo $title->textContent;
}

4. Forgetting to cast SimpleXML values to strings

<?php
echo $book->title;

This often works, but explicit casting is clearer and safer:

<?php
echo (string) $book->title;

5. Ignoring parser warnings for imperfect HTML

HTML from the web is often messy. Use:

<?php
libxml_use_internal_errors(true);
$dom->loadHTML($html);
libxml_clear_errors();

6. Assuming getElementsByTagName() supports advanced filtering

It only finds by tag name. If you need conditions such as class, attribute, or nested rules, use XPath.

Comparisons

ToolBest forWorks with HTMLWorks with XMLQuery powerEase of use
DOMDocumentGeneral parsing and traversalYesYesMediumMedium
DOMXPathPrecise searching in parsed documentsYesYesHighMedium
SimpleXMLSimple, clean XML readingNo practical HTML useYesLow to MediumEasy

DOMDocument vs SimpleXML

  • Use DOMDocument when you need flexibility, HTML support, or fine-grained node handling.
  • Use SimpleXML when reading straightforward XML and you want cleaner syntax.

getElementsByTagName() vs XPath

ApproachGood forLimitation
getElementsByTagName()Finding all elements of one tagCannot filter by attribute or complex structure
XPathSpecific queries like classes, attributes, nestingSlightly more syntax to learn

String search vs real parsing

ApproachProsCons
strpos() / regexQuick for tiny controlled textFragile and unreliable for real markup
ParserStructured, safer, maintainableRequires learning parser APIs
Take Quiz

Cheat Sheet

Quick reference

Load HTML with DOMDocument

$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML($html);
libxml_clear_errors();

Load XML with DOMDocument

$dom = new DOMDocument();
$dom->loadXML($xml);

Find elements by tag name

$nodes = $dom->getElementsByTagName('a');

Read text and attributes

$text = $node->textContent;
$href = $node->getAttribute('href');

Use XPath

$xpath = new DOMXPath($dom);
$nodes = $xpath->query('//a[@class="nav"]');

Load XML with SimpleXML

$data = simplexml_load_string($xml);

Access XML nodes and attributes

$title = (string) $data->book[0]->title;
$id = (string) $data->book[0]['id'];

Important rules

  • Use loadHTML() for HTML
  • Use loadXML() or simplexml_load_string() for XML
  • Check for null when selecting nodes
  • Cast SimpleXML values to strings when needed
  • Prefer XPath for advanced queries
  • Avoid regex for real HTML parsing

FAQ

How do I parse HTML in PHP?

Use DOMDocument::loadHTML() to load the HTML, then use getElementsByTagName() or DOMXPath to find elements and extract data.

How do I parse XML in PHP?

You can use DOMDocument::loadXML() or simplexml_load_string(). SimpleXML is easier for simple XML structures.

Should I use regex to parse HTML in PHP?

Usually no. HTML is nested and inconsistent, so regex is fragile. A parser like DOMDocument is more reliable.

What is XPath in PHP?

XPath is a query language for selecting nodes from an HTML or XML document. In PHP, you use it through DOMXPath.

Why does loadHTML() show warnings?

Real-world HTML is often imperfect. Use libxml_use_internal_errors(true) before parsing and libxml_clear_errors() after.

What is the difference between DOMDocument and SimpleXML?

DOMDocument is more flexible and supports HTML and XML. SimpleXML is simpler but mainly for straightforward XML.

How do I get an attribute value from an element in PHP?

With DOM, use $node->getAttribute('href'). With SimpleXML, use (string) $element['id'].

What happens if an element does not exist?

DOM selection may return null, so check before accessing properties like textContent.

Take Quiz

Mini Project

Description

Build a small PHP script that reads an HTML snippet and extracts all article links from it. This demonstrates loading HTML, querying elements, reading attributes, and collecting structured output.

Goal

Create a parser that returns an array of article titles and URLs from a block of HTML.

Requirements

  • Load a provided HTML string using PHP
  • Find all <a> elements inside <article> tags
  • Extract each link's text and href attribute
  • Skip links that do not have an href
  • Store the results in a PHP array and print them
Take Quiz

Keep learning

Related questions

View more