Learning Objectives – after this chapter you will be able to:
- Explain what XML is, why it is used to exchange data and where it is applied.
- Write well-formed XML: prolog, elements, tag pairs, empty tags, nesting rules and attributes.
- Describe an XML document as a tree of ancestors, descendants, parents and children.
- Read XML with SimpleXML and with the DOM, loop through elements and read attributes.
- Create XML from PHP data and from a MySQLi query, and query it with XPath.
What is XML?
XML (eXtensible Markup Language) is a markup language – the creators "cheated" a little with the acronym, since the X comes from eXtensible. XML was released by the W3C in 1998 to provide an easy-to-use, standardised way to store self-describing data – data that describes both its content and its structure.
Unlike HTML, XML has no predefined tags. You invent the tags that describe your data – <student>, <price>, <book> – which is what makes it extensible.
Communication between applications
XML by itself does nothing. It is a common ground standard. Its main benefit is that you can take data from one program – for example Microsoft SQL Server or MySQL – convert it into XML, and share that XML with many other programs and platforms. Each receiving platform converts the XML into the structure it normally uses. In this way two very different platforms can communicate.
What makes XML truly powerful is its international acceptance. Many individuals and companies have built XML interfaces for databases, programming languages, office applications, mobile phones and more. Earlier attempts at a standard data format that many different platforms could interpret failed; XML has largely succeeded.
Applications of XML
- Web services and data feeds – SOAP web services, RSS and Atom news feeds and site maps (
sitemap.xml) are XML. - Office documents – Microsoft Office (
.docx,.xlsx) and LibreOffice files are zipped XML. - Configuration files – many applications (Android, Java, .NET) keep settings in XML.
- Graphics and documents – SVG images, XHTML and e-book formats are XML.
- Mobile and voice applications – data sent to phones, and VoiceXML, which presents XML documents as audio.
- File converters – programs that convert existing documents (for example PDF) into XML.
Today JSON (Chapter 39) has replaced XML in many web APIs because it is shorter and maps directly to JavaScript objects. XML remains important for documents, feeds, configuration and enterprise systems, so every PHP developer should know both.
XML Syntax
If you know HTML, XML syntax is easy: it is still a markup language that relies on tags. The following XML document keeps track of the students of a Computer Applications course:
<?xml version="1.0" encoding="UTF-8"?>
<class_list>
<student>
<name>Danish</name>
<grade>A+</grade>
</student>
<student>
<name>Vikas</name>
<grade>A-</grade>
</student>
</class_list>Reading it, you can see that it has two students, Danish and Vikas. The data almost describes itself – one of the main reasons XML was created.
The XML prolog (optional)
The first line, with its special symbols and attributes, is the XML prolog or XML declaration:
<?xml version="1.0" encoding="UTF-8"?>
It states the version of XML and the character encoding used. It is optional, but if present it must be the very first thing in the document. Always include it; use UTF-8 (older documents use ISO-8859-1).
XML tags
XML tags are very similar to HTML tags. Each element is marked with an opening tag <element> and a closing tag </element>. The opening and closing tags together are a tag pair; all data that belongs to the element appears between them:
<name>Danish</name> <grade>A+</grade>
The empty (solo) tag
Elements that contain no text can replace the tag pair with one modified opening tag – a slash before the closing bracket: <element />. This tells the XML processor that the element is complete. Example: <photo src="danish.jpg" />.
Rules for well-formed XML
A document that follows the XML syntax rules is well-formed. If a rule is broken, the XML processor stops with an error.
- Every element must have a closing tag (or be an empty tag
<x/>). - Tags are case-sensitive:
<Student>must be closed with</Student>, not</student>. - Elements must be properly nested – the tag ordering rule: a tag opened inside another element must be closed before the outer element closes.
<b><i>text</i></b>is correct,<b><i>text</b></i>is not. - A document must have exactly one root element that contains all others.
- Attribute values must be quoted.
- Special characters must be written as entities:
<for <,&for &.
<?php
$docs = [
"good" => "<student><name>Danish</name></student>",
"case" => "<Student><name>Danish</name></student>",
"nesting" => "<student><name>Danish</student></name>",
"two roots" => "<a>1</a><b>2</b>",
"unquoted" => "<friend age=23>Samantha</friend>",
];
libxml_use_internal_errors(true); // collect errors instead of warnings
foreach ($docs as $label => $xml) {
$ok = simplexml_load_string($xml);
if ($ok !== false) {
echo "$label: well-formed<br>";
} else {
$err = libxml_get_errors()[0];
echo "$label: NOT well-formed – " . trim($err->message) . "<br>";
libxml_clear_errors();
}
}
?>good: well-formed case: NOT well-formed – Opening and ending tag mismatch: Student line 1 and student nesting: NOT well-formed – Opening and ending tag mismatch: name line 1 and student two roots: NOT well-formed – Extra content at the end of the document unquoted: NOT well-formed – AttValue: " or ' expected
(The original notes showed the student list with <Student> closed by </student> – the "case" test above shows why that document would be rejected.)
XML Elements
Elements are the meat and potatoes of XML. An element contains the opening and closing tags, child elements and data. In our document the student element contains two child elements:
<student> <name>Danish</name> <grade>A+</grade> </student>
XML stores data in a self-explanatory way by putting information into elements: if a piece of text is a title, it goes into a title element.
XML Attributes
Attributes specify additional information about an element – a way of specialising generic elements. An attribute appears inside the opening tag, and its value must be quoted:
<element attributeName="value"> <friend age="23">Samantha</friend>
Data can be stored in child elements or in attributes. A common guideline: use elements for the data itself and attributes for metadata such as ids, units or types: <price currency="INR">499</price>.
The XML Tree
The great benefit of XML is that the document itself describes the structure of the data – it fits naturally into a tree, like a family tree with the earliest ancestor at the top. The following document was created by an enterprising kid to keep the inventory of her lemonade stand:
<?xml version="1.0" encoding="UTF-8"?>
<inventory>
<drink>
<lemonade>
<price>2.50</price>
<amount>20</amount>
</lemonade>
<pop>
<price>1.50</price>
<amount>10</amount>
</pop>
</drink>
<snack>
<chips>
<price>4.50</price>
<amount>60</amount>
</chips>
</snack>
</inventory>Figure 38.1 – lemonade.xml as a tree
XML tree rules
- Descendants – if element A is contained by element B, then A is a descendant of B. In lemonade.xml every element is a descendant of
inventory, because it is the root. - Ancestors – if element B contains element A, then B is an ancestor of A.
drinkis an ancestor oflemonadeandpop. - Parent / child – the direct container is the parent; directly contained elements are its children.
- Siblings – children of the same parent (
lemonadeandpop).
Reading XML with SimpleXML
SimpleXML (PHP 5 and later) is an easy way of getting an element's text and attributes if you know the layout of the XML document. Compared with the DOM or the event-based Expat parser, SimpleXML needs just a few lines of code. It converts the XML document into an object:
- Elements become properties of the
SimpleXMLElementobject; when there is more than one element with the same name on a level, they can be used like an array. - Attributes are accessed like associative-array elements:
$element['age']. - Element data (text) is converted to a string with
(string)or by echoing it.
<?xml version="1.0" encoding="UTF-8"?> <note> <to>Rakesh</to> <from>Nitin</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note>
We want to output the element names and data from the XML file above:
<?php
$xml = simplexml_load_file("note.xml");
echo $xml->getName() . "<br>";
foreach ($xml->children() as $child) {
echo $child->getName() . ": " . $child . "<br>";
}
?>note to: Rakesh from: Nitin heading: Reminder body: Don't forget me this weekend!
Navigating, attributes and XPath
<?xml version="1.0" encoding="UTF-8"?>
<library>
<book id="b1" category="programming">
<title>PHP: Basics to Advance</title>
<price currency="INR">499</price>
</book>
<book id="b2" category="database">
<title>MySQL in Practice</title>
<price currency="INR">399</price>
</book>
<book id="b3" category="programming">
<title>JavaScript Essentials</title>
<price currency="INR">349</price>
</book>
</library><?php
$lib = simplexml_load_file("books.xml");
echo "Number of books: " . count($lib->book) . "<br>";
echo "Second title: " . $lib->book[1]->title . "<br>";
foreach ($lib->book as $b) {
echo "[{$b['id']}] {$b->title} – {$b->price['currency']} {$b->price} ({$b['category']})<br>";
}
$total = 0;
foreach ($lib->book as $b) $total += (float) $b->price;
echo "Total price: $total<br>";
// XPath: titles of programming books costing more than 300
foreach ($lib->xpath("//book[@category='programming' and price > 300]/title") as $t) {
echo "XPath result: $t<br>";
}
?>Number of books: 3 Second title: MySQL in Practice [b1] PHP: Basics to Advance – INR 499 (programming) [b2] MySQL in Practice – INR 399 (database) [b3] JavaScript Essentials – INR 349 (programming) Total price: 1247 XPath result: PHP: Basics to Advance XPath result: JavaScript Essentials
The DOM (Document Object Model)
The W3C DOM provides a standard set of objects for HTML and XML documents and a standard interface for accessing and manipulating them. It is divided into parts (Core, XML and HTML) and levels (DOM Level 1/2/3):
- Core DOM – a standard set of objects for any structured document.
- XML DOM – a standard set of objects for XML documents.
- HTML DOM – a standard set of objects for HTML documents.
XML parsing
To read and update – create and manipulate – an XML document you need an XML parser. There are two basic types:
- Tree-based parser – transforms the whole document into a tree structure in memory and gives access to the tree elements. The DOM parser (and SimpleXML) are tree-based.
- Event-based parser – views the document as a series of events (start tag, text, end tag); when an event occurs it calls a function to handle it. PHP's XML Parser (Expat) and XMLReader are event/stream-based and use little memory for very large files.
The DOM sees <from>Nitin</from> as a tree: Level 1 – the XML document; Level 2 – the root element <from>; Level 3 – the text node "Nitin".
Load and output XML
We initialise the XML parser, load the XML and output it:
<?php
$xmlDoc = new DOMDocument();
$xmlDoc->load("note.xml");
print $xmlDoc->saveXML();
?>Rakesh Nitin Reminder Don't forget me this weekend!
The browser shows only the text, because it treats the unknown tags as HTML. If you select View Source you see the complete XML. saveXML() puts the internal XML document into a string so that it can be output.
Looping through XML
We initialise the parser, load the XML and loop through all child nodes of the <note> element:
<?php
$xmlDoc = new DOMDocument();
$xmlDoc->load("note.xml");
$x = $xmlDoc->documentElement;
foreach ($x->childNodes as $item) {
print $item->nodeName . " = " . $item->nodeValue . "<br>";
}
?>#text = to = Rakesh #text = from = Nitin #text = heading = Reminder #text = body = Don't forget me this weekend! #text =
You see empty text nodes (#text) between the elements. When XML is generated it often contains white space between the nodes; the DOM parser treats it as ordinary text nodes, which can cause problems if you are not aware of them. Load the document with $xmlDoc->preserveWhiteSpace = false; or skip nodes whose nodeType is not XML_ELEMENT_NODE:
<?php
$xmlDoc = new DOMDocument();
$xmlDoc->preserveWhiteSpace = false;
$xmlDoc->load("note.xml");
foreach ($xmlDoc->documentElement->childNodes as $item) {
if ($item->nodeType == XML_ELEMENT_NODE) {
print $item->nodeName . " = " . $item->nodeValue . "<br>";
}
}
echo "Number of 'body' elements: " . $xmlDoc->getElementsByTagName("body")->length;
?>to = Rakesh from = Nitin heading = Reminder body = Don't forget me this weekend! Number of 'body' elements: 1
Creating XML with PHP
With the DOM
<?php
$doc = new DOMDocument("1.0", "UTF-8");
$doc->formatOutput = true;
$root = $doc->createElement("class_list");
$doc->appendChild($root);
foreach (["Danish" => "A+", "Vikas" => "A-"] as $name => $grade) {
$s = $doc->createElement("student");
$s->setAttribute("batch", "2026");
$s->appendChild($doc->createElement("name", $name));
$s->appendChild($doc->createElement("grade", $grade));
$root->appendChild($s);
}
$doc->save("new_class_list.xml");
echo "<pre>" . htmlspecialchars($doc->saveXML()) . "</pre>";
?><?xml version="1.0" encoding="UTF-8"?>
<class_list>
<student batch="2026">
<name>Danish</name>
<grade>A+</grade>
</student>
<student batch="2026">
<name>Vikas</name>
<grade>A-</grade>
</student>
</class_list>From a MySQLi query with SimpleXML
A typical job is exporting database data as XML for another system:
<?php
$conn = new mysqli("localhost", "root", "", "phpbook");
$xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><courses/>');
foreach ($conn->query("SELECT course_id, course_name, duration, fee FROM courses") as $row) {
$c = $xml->addChild("course");
$c->addAttribute("id", $row["course_id"]);
$c->addChild("name", htmlspecialchars($row["course_name"]));
$c->addChild("duration", $row["duration"]);
$c->addChild("fee", $row["fee"]);
}
$dom = dom_import_simplexml($xml)->ownerDocument;
$dom->formatOutput = true;
echo "<pre>" . htmlspecialchars($dom->saveXML()) . "</pre>";
?><?xml version="1.0" encoding="UTF-8"?>
<courses>
<course id="1">
<name>Core PHP</name>
<duration>3 months</duration>
<fee>4500.00</fee>
</course>
<course id="2">
<name>Advance PHP</name>
<duration>2 months</duration>
<fee>6000.00</fee>
</course>
<course id="3">
<name>MySQL</name>
<duration>1 month</duration>
<fee>2500.00</fee>
</course>
<course id="4">
<name>Laravel</name>
<duration>2 months</duration>
<fee>8000.00</fee>
</course>
</courses>To send XML to a client program instead of displaying it, output header("Content-Type: application/xml"); followed by echo $xml->asXML();.
Key Takeaways
- XML stores self-describing data with tags you define; it is a W3C standard for exchanging data between platforms.
- Well-formed XML: optional prolog first, one root, every tag closed, case-sensitive tags, correct nesting, quoted attributes.
- An XML document is a tree of parents, children, siblings, ancestors and descendants.
- SimpleXML (
simplexml_load_file,->children(),['attr'],xpath()) is the quickest way to read XML. - The DOM (
DOMDocument,load,childNodes,createElement,saveXML) reads and builds XML; beware of white-space text nodes. - Tree-based parsers load the whole document; event-based parsers (Expat, XMLReader) stream large files.
Program File
Extract the ZIP into C:\xampp\htdocs. It creates the folder phpbook/ch38 used in the file labels above; open the programs at http://localhost/phpbook/… with Apache (and MySQL, where needed) started in the XAMPP Control Panel.
Question / Answer (15 questions)
MCQ Test : Check Your Understanding (5 questions)
Select an option and press Check Answer, or answer all questions and press Submit Test to see your score. Each answer comes with an explanation.
Bibliography/References
The notes on this page are the author’s own compilation from the e-book PHP: Basics to Advance. Every program was run on Apache with PHP 8 and MariaDB, and the output shown is the real result of that run. The works listed below were consulted and are cited for attribution and further reading. Product names and trademarks belong to their respective owners.
- W3C. (2008). Extensible Markup Language (XML) 1.0 (Fifth Edition). https://www.w3.org/TR/xml/
- The PHP Group. (n.d.). PHP Manual – SimpleXML. https://www.php.net/manual/en/book.simplexml.php
- The PHP Group. (n.d.). PHP Manual – Document Object Model (DOM). https://www.php.net/manual/en/book.dom.php
- The PHP Group. (n.d.). PHP Manual – XML Parser (Expat). https://www.php.net/manual/en/book.xml.php
- MDN contributors. (n.d.). XML introduction. MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/XML/XML_introduction