Question
How can HTML or XML be parsed in PHP so that information can be extracted from it efficiently and safely?
For example, how do you load a document, navigate its elements and attributes, and read specific values from it using PHP?
Short Answer
By the end of this page, you will understand the main ways to parse and process HTML and XML in PHP. You will learn when to use DOMDocument, SimpleXML, and XPath, how to extract text and attributes, and how to avoid common mistakes when dealing with imperfect HTML or structured XML data.
Concept
PHP provides built-in tools for reading structured markup such as HTML and XML. Parsing means converting a markup string or file into a structure that your code can navigate.
The main PHP tools for this are:
DOMDocument— good for working with both HTML and XML as a tree of nodesSimpleXML— simpler syntax for reading well-formed XMLDOMXPath— used withDOMDocumentto query nodes using XPath expressions
Why this matters:
- Web scraping often involves reading HTML and extracting links, headings, prices, or metadata.
- APIs may return XML that needs to be read and converted into application data.
- Configuration files and feeds may be stored as XML.
- Automated scripts often need to process documents without manual inspection.
A key idea is that HTML and XML are both tree structures. Elements can contain child elements, text, and attributes. Once parsed, PHP lets you move through that tree and access the parts you need.
There is also an important difference:
- XML must be well-formed and strict.
- HTML is often messy, so parsers may need to be more tolerant.
In PHP, DOMDocument is often the most flexible choice because it supports:
- loading markup from strings or files
- reading elements and attributes
- modifying documents
- querying with XPath
For simple XML, SimpleXML is usually easier to read and write in beginner code.
Mental Model
Think of an HTML or XML document like a family tree.
- Each tag is a person in the tree.
- Parent tags contain child tags.
- Attributes are like labels attached to a person.
- Text inside a tag is the content that person holds.
For example:
<book id="101">
<title>PHP Basics</title>
</book>
Here:
bookis the parent nodetitleis its child nodeid="101"is an attributePHP Basicsis the text content
Parsing means turning the raw text into this tree so PHP can walk through it instead of treating it like plain text.
Syntax and Examples
Using DOMDocument for HTML
<?php
$html = '<html><body><h1>Hello</h1><a href="/about">About</a></body></html>';
$dom = new DOMDocument();
libxml_use_internal_errors(true); // suppress warnings for imperfect HTML
$dom->loadHTML($html);
libxml_clear_errors();
$headings = $dom->getElementsByTagName('h1');
echo $headings->item(0)->textContent; // Hello
$links = $dom->getElementsByTagName('a');
echo $links->item(0)->getAttribute('href'); // /about
Explanation:
loadHTML()parses the HTML string.getElementsByTagName()finds all matching elements.textContentgets the text inside an element.getAttribute()reads an attribute value.
Using XPath with HTML
<?php
$html = '<html><body><div class="product"><span>$19</span></div></body></html>';
$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML($html);
libxml_clear_errors();
$xpath = new DOMXPath($dom);
$nodes = $xpath->query('//div[@class="product"]/span');
echo $nodes->item(0)->textContent; // $19
XPath is useful when:
- the document has nested structure
- you need specific elements based on attributes
- simple tag-name searches are not enough
Using SimpleXML for XML
<?php
$xml = <<<XML
<books>
<book id="1">
<title>PHP Basics</title>
<author>Jane Doe</author>
</book>
</books>
XML;
$data = simplexml_load_string($xml);
echo $data->book->title; // PHP Basics
echo $data->book['id']; // 1
Explanation:
simplexml_load_string()parses XML into an easy-to-use object.- Child elements can be accessed like properties.
- Attributes can be accessed with array syntax.
Loading from a file
<?php
$xml = simplexml_load_file('books.xml');
echo $xml->book->title;
This is convenient for XML files stored locally.
Step by Step Execution
Consider this XML example:
<?php
$xml = <<<XML
<user>
<name>Alice</name>
<email>alice@example.com</email>
</user>
XML;
$user = simplexml_load_string($xml);
echo $user->name;
Step by step:
$xmlstores the XML text as a string.simplexml_load_string($xml)reads that string and builds an object representing the XML tree.- The root node is
<user>, so$userrepresents theuserelement. $user->nameaccesses the child element<name>.echo $user->name;printsAlice.
Now a DOM example:
<?php
$html = '<ul><li>One</li><li>Two</li></ul>';
$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML($html);
libxml_clear_errors();
$items = $dom->getElementsByTagName('li');
echo $items->item(0)->textContent;
echo $items->item(1)->textContent;
What happens:
- PHP creates a new
DOMDocumentobject. loadHTML()parses the HTML into DOM nodes.getElementsByTagName('li')returns a collection of all<li>elements.item(0)gets the first<li>node.textContentreturnsOne.item(1)returnsTwo.
This is the basic pattern for many parsing tasks:
- load document
- find nodes
- read text or attributes
- process results
Real World Use Cases
Web scraping
You might parse HTML to extract:
- article titles
- product prices
- image URLs
- links from search results
Reading XML API responses
Some APIs return XML instead of JSON. PHP can parse that XML and extract values such as:
- order IDs
- customer names
- status codes
Processing RSS or Atom feeds
Feeds are XML documents. You can use PHP to read:
- blog post titles
- publication dates
- feed links
Importing data files
A company may export inventory, user lists, or settings in XML. PHP scripts can read the file and insert the data into a database.
Server-side content transformation
Applications may load an HTML fragment, update certain nodes, and output changed markup.
Real Codebase Usage
In real projects, developers usually combine parsing with validation, error handling, and queries.
Common patterns
Guard clauses
Check whether parsing succeeded before using the result.
<?php
$xml = simplexml_load_string($rawXml);
if ($xml === false) {
exit('Invalid XML');
}
Extracting repeated elements
<?php
$xml = simplexml_load_file('books.xml');
foreach ($xml->book as $book) {
echo $book->title . PHP_EOL;
}
Using XPath for precise selection
<?php
$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML($html);
libxml_clear_errors();
$xpath = new DOMXPath($dom);
foreach ($xpath->query('//a[@href]') as $link) {
echo $link->getAttribute('href') . PHP_EOL;
}
Reading attributes safely
<?php
$id = $book['id'] ?? null;
Normalizing extracted values
Developers often trim whitespace or convert strings after extraction.
<?php
$title = trim((string) $book->title);
Practical advice
- Use
SimpleXMLfor small, clean XML documents. - Use
DOMDocumentwith XPath when you need more control. - Treat external markup as untrusted input.
- Always check for missing nodes before using them.
Common Mistakes
1. Treating HTML or XML as plain text with string functions
Beginners sometimes do this:
<?php
$title = explode('<title>', $html)[1];
Why it is a problem:
- breaks if formatting changes
- fails on nested tags
- is hard to maintain
Use a parser instead.
2. Forgetting that HTML may be invalid or messy
Broken HTML can trigger warnings.
<?php
$dom = new DOMDocument();
$dom->loadHTML($html); // may produce warnings
Safer approach:
<?php
libxml_use_internal_errors(true);
$dom = new DOMDocument();
$dom->loadHTML($html);
libxml_clear_errors();
3. Assuming a node always exists
Broken code:
<?php
echo $dom->getElementsByTagName('h1')->item(0)->textContent;
If there is no h1, item(0) is null.
Safer code:
<?php
$node = $dom->getElementsByTagName('h1')->item(0);
if ($node !== null) {
echo $node->textContent;
}
4. Confusing XML rules with HTML rules
XML must be well-formed.
Broken XML:
<book>
<title>PHP
</book>
The title tag is not closed properly, so XML parsing fails.
5. Forgetting to cast SimpleXML values to strings
Sometimes you want a real string value.
<?php
$title = (string) $book->title;
This helps when trimming, comparing, or storing the value.
6. Using the wrong tool for the job
SimpleXMLis easier for simple XML.DOMDocumentis better for HTML and advanced traversal.- XPath is better when you need targeted selection.
Comparisons
| Tool | Best for | Strengths | Limitations |
|---|---|---|---|
SimpleXML | Simple, well-formed XML | Easy syntax, beginner-friendly | Less flexible for complex document manipulation |
DOMDocument | HTML or XML tree processing | Powerful, editable, works well with XPath | More verbose |
DOMXPath | Querying DOM nodes | Precise selection by structure and attributes | Requires DOMDocument |
SimpleXML vs DOMDocument
| Feature | SimpleXML | DOMDocument |
|---|---|---|
| Ease of use | Easier | More detailed |
| Works well with XML | Yes | Yes |
| Works well with HTML | Not ideal | Yes |
| Querying complex structures | Limited | Strong with XPath |
| Editing documents | Basic | Powerful |
When to choose which
- Choose
SimpleXMLwhen the input is clean XML and you want readable code. - Choose
DOMDocumentwhen parsing HTML or doing advanced node traversal. - Add XPath when selecting elements by attribute, nesting, or position.
Cheat Sheet
// SimpleXML from string
$xml = simplexml_load_string($xmlString);
// SimpleXML from file
$xml = simplexml_load_file('data.xml');
// DOMDocument for HTML
$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML($html);
libxml_clear_errors();
// DOMDocument for XML
$dom = new DOMDocument();
$dom->loadXML($xmlString);
// Find tags
$nodes = $dom->getElementsByTagName('a');
// Read text
$text = $nodes->item(0)->textContent;
// Read attribute
$href = $nodes->item(0)->getAttribute('href');
// XPath query
$xpath = new DOMXPath($dom);
$result = $xpath->query('//a[@href]');
Quick rules:
- Use
loadHTML()for HTML. - Use
loadXML()for XML. - Use
simplexml_load_string()for simple XML strings. - Use XPath when tag names alone are not enough.
- Check for missing nodes before reading
textContent. - Cast
SimpleXMLvalues to strings when needed. - Suppress and clear libxml warnings when parsing messy HTML.
FAQ
How do I parse HTML in PHP?
Use DOMDocument with loadHTML(), then access nodes with getElementsByTagName() or XPath.
How do I parse XML in PHP?
For simple cases, use simplexml_load_string() or simplexml_load_file(). For more control, use DOMDocument with loadXML().
Should I use regex to parse HTML or XML in PHP?
Usually no. HTML and XML are nested tree structures, and parsers are much more reliable than regular expressions for this job.
What is XPath in PHP?
XPath is a query language for selecting nodes in an HTML or XML document. In PHP, it is used through DOMXPath.
Why does loadHTML() show warnings?
HTML from real websites is often imperfect. Use libxml_use_internal_errors(true) before parsing and clear errors afterward.
What is the difference between SimpleXML and DOMDocument?
SimpleXML is easier for reading clean XML. DOMDocument is more powerful and better for HTML or complex traversal.
Can PHP extract attributes from HTML or XML tags?
Yes. In DOM, use getAttribute(). In SimpleXML, attributes can be accessed like $node['attrName'].
How do I loop through repeated XML elements in PHP?
Use foreach.
<?php
foreach ($xml->book as $book) {
echo $book->title;
}
Mini Project
Description
Build a small PHP script that reads an XML product catalog and prints a clean summary of each product. This demonstrates loading XML, accessing child elements, reading attributes, and looping through repeated nodes.
Goal
Parse an XML catalog in PHP and display each product's ID, name, and price.
Requirements
Requirement 1 Requirement 2 Requirement 3
Keep learning
Related questions
Allow Only Numeric Input (0-9) in HTML Input Using jQuery
Learn how to allow only digits 0-9 in an HTML input using jQuery, with examples, validation tips, common mistakes, and best practices.
Apply CSS !important with jQuery .css()
Learn why jQuery .css() cannot set !important and how to use CSSStyleDeclaration.setProperty() to apply inline important styles safely.
CSS ::before and ::after on Input Elements
Learn why CSS ::before and ::after usually do not work on input elements, what replaced elements are, and practical alternatives.