W3docs

xml_parse()

The xml_parse() function is a PHP built-in function that parses XML data. When parsing an XML file using the SimpleXML library or other XML parsing libraries in

What is xml_parse()?

The xml_parse() function is a PHP built-in function that parses XML data. It belongs to PHP's XML Parser extension and implements a SAX-style (Simple API for XML) streaming parser. Unlike tree-based parsers, it processes XML sequentially, triggering callback functions as it encounters elements, attributes, and character data. This makes it highly efficient for parsing large XML files without loading the entire document into memory.

The xml_parse() function is useful when you need to parse XML data in PHP, for example, to extract data from an XML file, to transform XML data into another format, or to process XML streams in real time.

Syntax

The syntax of the xml_parse() function is as follows:

xml_parse($parser, $data, $is_final = false): int

Parameters

  • $parser — the XML parser handle returned by xml_parser_create(). This is the object that holds the parsing state.
  • $data — a chunk (or all) of the XML text to feed into the parser.
  • $is_final — set to true when you pass the last chunk of data. As long as it is false, the parser keeps its state so you can call xml_parse() again with the next chunk.

Return value

xml_parse() returns 1 (truthy) on success and 0 (falsy) on failure. It does not return the parsed data — the parsed content is delivered to the handler callbacks you registered. When it returns 0, inspect the error with xml_get_error_code() and xml_error_string().

Usage Examples

Let's take a look at some practical examples of using xml_parse() in PHP.

Example 1: Parsing XML with Event Handlers

xml_parse() is a SAX parser: it does not build a document for you, it fires events. To get any output you must register handler functions. The example below uses an inline XML string so it runs as-is, with no external file:

<?php
$xml = <<<XML
<?xml version="1.0"?>
<note>
  <to>Tove</to>
  <from>Jani</from>
</note>
XML;

$parser = xml_parser_create();
// Keep element names in their original case instead of upper-casing them.
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);

xml_set_element_handler(
    $parser,
    fn($p, $name, $attrs) => print("Start: $name\n"),
    fn($p, $name)         => print("End:   $name\n")
);
xml_set_character_data_handler($parser, function ($p, $data) {
    $data = trim($data);
    if ($data !== "") {
        echo "Text:  $data\n";
    }
});

if (!xml_parse($parser, $xml, true)) {
    $code = xml_get_error_code($parser);
    echo "Error: " . xml_error_string($code)
       . " at line " . xml_get_current_line_number($parser);
}

xml_parser_free($parser);

This prints:

Start: note
Start: to
Text:  Tove
End:   to
Start: from
Text:  Jani
End:   from
End:   note

The parser walks the document top-to-bottom and calls your start-element, character-data, and end-element handlers in document order. We register them with xml_set_element_handler() and xml_set_character_data_handler(), pass everything in one call ($is_final = true), and free the parser with xml_parser_free().

Example 2: Parsing a file or data stream in chunks

The real strength of xml_parse() is incremental parsing: feed the document a piece at a time so even a multi-gigabyte file never has to fit in memory. Pass $is_final = false for every chunk except the last:

<?php
$parser = xml_parser_create();
xml_set_element_handler(
    $parser,
    fn($p, $name, $attrs) => print("<$name>\n"),
    fn($p, $name)         => print("</$name>\n")
);

$handle = fopen("data.xml", "r");          // or php://stdin for a stream
while (($chunk = fread($handle, 4096)) !== false) {
    $isFinal = feof($handle);
    if (!xml_parse($parser, $chunk, $isFinal)) {
        $code = xml_get_error_code($parser);
        echo "XML error: " . xml_error_string($code)
           . " at line " . xml_get_current_line_number($parser);
        break;
    }
    if ($isFinal) {
        break;
    }
}
fclose($handle);
xml_parser_free($parser);

Because the parser keeps its state between calls, an element can start in one chunk and end in another — xml_parse() stitches the events together correctly. This is what makes the function suitable for large XML files where a tree-based approach like SimpleXML would exhaust memory.

Example 3 (reference): parsing a file in one shot

If your XML is small enough to fit in memory, you can read it with file_get_contents() and hand the whole string to xml_parse() in a single call. Handlers can also be named functions (string names) instead of closures:

$xml_parser = xml_parser_create();
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0);

// Define handler functions
function startElement($parser, $name, $attrs) {
    echo "Start element: $name\n";
}
function endElement($parser, $name) {
    echo "End element: $name\n";
}
function characterData($parser, $data) {
    echo "Data: $data\n";
}

// Set handlers
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");

$xml_data = file_get_contents("data.xml");
if (!xml_parse($xml_parser, $xml_data, true)) {
    $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 sets an option to turn off case folding. It then defines three callback functions: startElement() for opening tags, endElement() for closing tags, and characterData() for text content. These handlers are registered using xml_set_element_handler() and xml_set_character_data_handler().

The script reads "data.xml" and passes it to xml_parse(). As the parser streams through the XML, it automatically calls the registered handlers. If an error occurs during parsing, the code retrieves the error code and message using xml_get_error_code() and xml_error_string(), and outputs a descriptive error. Finally, it frees the parser memory with xml_parser_free().

Common pitfalls

  • No handlers, no output. xml_parse() only fires the callbacks you registered. With no handlers set it parses successfully but does nothing visible.
  • Character data arrives in pieces. A single text node may trigger xml_set_character_data_handler more than once (for example, around entity references), so accumulate text into a buffer instead of assuming you get it all at once.
  • Whitespace counts as character data. Indentation between tags fires the character-data handler. Use trim() (as in Example 1) if you only care about real text.
  • Always free the parser. Call xml_parser_free() when done; on PHP 8+ the handle is an XMLParser object that is garbage-collected, but freeing explicitly keeps memory tight in long-running scripts.

Conclusion

PHP's xml_parse() function is the engine of the SAX-style XML Parser extension. Instead of returning a document, it streams through XML and fires the handlers you register, returning 1 on success and 0 on failure. Its $is_final parameter lets you parse data in chunks, which is why it stays memory-efficient even on huge files. Pair it with xml_parser_create(), the handler-setup functions, and xml_parser_free(), and you have a fast, low-memory way to process XML in PHP.

Practice

Practice
What is XML Parser in PHP?
What is XML Parser in PHP?
Was this page helpful?