xml_parse_into_struct()
The xml_parse_into_struct() function is a PHP built-in function that parses XML data into a multidimensional array. When parsing an XML file using the SimpleXML
The xml_parse_into_struct() function is a PHP built-in function that parses XML data into a multidimensional array. It belongs to the XML Parser extension and exposes a SAX-style, low-level view of a document: instead of giving you a navigable object tree, it flattens the XML into a flat list of "events" (open tag, character data, close tag) that you can iterate over.
This page covers what the function returns, its full signature, how to read the two output arrays it fills ($values and $index), and two complete, runnable examples.
Ensure the xml extension is enabled in your php.ini configuration before using this function (it is bundled and enabled by default in most PHP builds).
When to use it
xml_parse_into_struct() is useful when you need to walk through every element of an XML document in document order — for example, to convert XML into another format, to flatten deeply nested data, or to analyze the structure of a file.
For most everyday tasks, the object-oriented SimpleXML API (simplexml_load_string() / simplexml_load_file()) is easier to read. Reach for xml_parse_into_struct() when you specifically want the linear, event-style array that it produces.
Syntax
The signature of the xml_parse_into_struct() function is as follows:
xml_parse_into_struct($parser, $data, &$values, &$index): int| Parameter | Description |
|---|---|
$parser | The XML parser resource returned by xml_parser_create(). |
$data | A string containing the XML to be parsed. |
&$values | Passed by reference. Filled with one associative array per parsing event. |
&$index | Passed by reference. Maps each tag name to the positions of its events inside $values, so you can jump straight to a given element. |
It returns 0 on failure and a non-zero value on success.
The shape of $values
Each entry in $values describes a single event and has these keys:
tag— the element name.type— one ofopen(start tag with children),close(end tag),complete(a self-contained element), orcdata(character data between tags).level— the nesting depth, starting at1.value— the text content, when present.attributes— an associative array of the element's attributes, when present.
Usage Examples
Let's take a look at some practical examples of using xml_parse_into_struct() in PHP. Both use this data.xml document:
<?xml version="1.0"?>
<library>
<book>
<title>PHP Basics</title>
<author>Jane Doe</author>
</book>
<book>
<title>XML Parsing</title>
<author>John Smith</author>
</book>
</library>Example 1: Parsing XML Data into a Structured Array
Read the file, parse it into $values and $index, and report any error:
$xml_parser = xml_parser_create();
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0);
$xml_data = file_get_contents("data.xml");
$values = array();
$index = array();
if (!xml_parse_into_struct($xml_parser, $xml_data, $values, $index)) {
$error_message = xml_error_string(xml_get_error_code($xml_parser));
$error_line = xml_get_current_line_number($xml_parser);
echo "XML Parsing Error: $error_message at line $error_line";
}
xml_parser_free($xml_parser);This code creates an XML parser using xml_parser_create() and disables case folding (with xml_parser_set_option()) so tag names keep their original case. It reads the XML file into $xml_data, initializes empty $values and $index arrays, then calls xml_parse_into_struct() to populate them. If parsing fails it retrieves the code with xml_get_error_code(), turns it into a message with xml_error_string(), and prints the line number. Finally it releases the parser with xml_parser_free().
After a successful parse, $index lets you jump straight to every occurrence of a tag. For the document above it looks like this:
// $index
[
"library" => [0, 7, 14, 15],
"book" => [1, 3, 5, 6, 8, 10, 12, 13],
"title" => [2, 9],
"author" => [4, 11],
]Each number is an offset into $values. So $index["title"] tells you the two <title> events live at positions 2 and 9. You can use that to pull values directly:
foreach ($index["title"] as $i) {
echo "Title: " . $values[$i]["value"] . "\n";
}Output:
Title: PHP Basics
Title: XML ParsingExample 2: Analyzing the Structure of an XML File
To inspect the document's shape, iterate over $values and react to each event's type. The setup is the same as Example 1; the new part is the loop:
$xml_parser = xml_parser_create();
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0);
$xml_data = file_get_contents("data.xml");
$values = array();
$index = array();
if (!xml_parse_into_struct($xml_parser, $xml_data, $values, $index)) {
$error_message = xml_error_string(xml_get_error_code($xml_parser));
$error_line = xml_get_current_line_number($xml_parser);
echo "XML Parsing Error: $error_message at line $error_line";
}
xml_parser_free($xml_parser);
foreach ($values as $value) {
if ($value["type"] == "open") {
echo "Start element: " . $value["tag"] . "<br/>";
} else if ($value["type"] == "close") {
echo "End element: " . $value["tag"] . "<br/>";
}
}This loop checks the type of each event: "open" prints a start tag, "close" prints an end tag. For the sample document it outputs:
Start element: library
Start element: book
End element: book
Start element: book
End element: book
End element: libraryNote that <title> and <author> do not appear here: because they contain only text, they arrive as complete events rather than separate open/close pairs. Add a case "complete" (or check $value["value"]) if you need their content too.
Conclusion
PHP's xml_parse_into_struct() function flattens XML into a linear array of parsing events, giving you a low-level, SAX-style way to read a document. The key to using it well is understanding the two output arrays: $values holds the ordered events (each with tag, type, level, value, and attributes), and $index maps tag names to their positions so you can reach any element directly.
For navigating structured XML in everyday code, prefer SimpleXML; for the event-stream view shown here, xml_parse_into_struct() (or the lower-level xml_parse() with handlers) is the right tool.