This file keeps the documentation examples in a form that is easy to copy, run, and adapt.
Normalized hierarchy for traversal and wrappers
Streaming extraction for large XML
Streaming extraction with custom hierarchy keys
Traversal wrapper over the normalized hierarchy
Custom key names for one-shot conversion
Readable output for application code and JSON
Readable streaming output
Compose the current node when you already control the XMLReader cursor
FastXmlToArray::convert()Normalized hierarchy for traversal and wrappers.
use SbWereWolf\XmlNavigator\Conversion\FastXmlToArray;
$xml = <<<'XML'
<feed generated_at="2026-03-28T09:00:00Z">
<offer id="206111" available="true">
<name>USB-C Dock</name>
<price currency="USD">129.90</price>
<picture>https://cdn.example.test/1.jpg</picture>
<picture>https://cdn.example.test/2.jpg</picture>
</offer>
</feed>
XML;
$result = FastXmlToArray::convert($xml);
var_export($result);
Output:
array (
'n' => 'feed',
'a' =>
array (
'generated_at' => '2026-03-28T09:00:00Z',
),
's' =>
array (
0 =>
array (
'n' => 'offer',
'a' =>
array (
'id' => '206111',
'available' => 'true',
),
's' =>
array (
0 =>
array (
'n' => 'name',
'v' => 'USB-C Dock',
),
1 =>
array (
'n' => 'price',
'v' => '129.90',
'a' =>
array (
'currency' => 'USD',
),
),
2 =>
array (
'n' => 'picture',
'v' => 'https://cdn.example.test/1.jpg',
),
3 =>
array (
'n' => 'picture',
'v' => 'https://cdn.example.test/2.jpg',
),
),
),
),
)
FastXmlParser::extractHierarchy()Streaming extraction for large XML. This is the recommended workflow when the file is large and only some nodes matter.
use SbWereWolf\XmlNavigator\Parsing\FastXmlParser;
$uri = tempnam(sys_get_temp_dir(), 'xml-extract-kit-');
file_put_contents($uri, <<<'XML'
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<offer id="1">
<name>Keyboard</name>
<price>49.90</price>
</offer>
<service id="s-1">
<name>Warranty</name>
</service>
<offer id="2">
<name>Mouse</name>
<price>19.90</price>
</offer>
</catalog>
XML);
$reader = XMLReader::open($uri);
if ($reader === false) {
throw new RuntimeException('Cannot open XML file.');
}
$offers = FastXmlParser::extractHierarchy(
$reader,
static fn (XMLReader $cursor): bool =>
$cursor->nodeType === XMLReader::ELEMENT
&& $cursor->name === 'offer'
);
foreach ($offers as $offer) {
var_export($offer);
echo PHP_EOL;
}
$reader->close();
unlink($uri);
FastXmlParser::extractHierarchy() with custom keysThe same hierarchy-first workflow can use your own internal key names.
use SbWereWolf\XmlNavigator\Parsing\FastXmlParser;
$uri = tempnam(sys_get_temp_dir(), 'xml-extract-kit-');
file_put_contents($uri, <<<'XML'
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<offer id="1">
<name>Keyboard</name>
<price>49.90</price>
</offer>
<service id="s-1">
<name>Warranty</name>
</service>
<offer id="2">
<name>Mouse</name>
<price>19.90</price>
</offer>
</catalog>
XML);
$reader = XMLReader::open($uri);
if ($reader === false) {
throw new RuntimeException('Cannot open XML file.');
}
$offers = FastXmlParser::extractHierarchy(
$reader,
static fn (XMLReader $cursor): bool =>
$cursor->nodeType === XMLReader::ELEMENT
&& $cursor->name === 'offer',
'value',
'attributes',
'name',
'children',
);
foreach ($offers as $offer) {
var_export($offer);
echo PHP_EOL;
}
$reader->close();
unlink($uri);
XmlElementTraversal wrapper over the normalized hierarchy.
use SbWereWolf\XmlNavigator\Conversion\FastXmlToArray;
use SbWereWolf\XmlNavigator\Navigation\XmlElement;
$xml = <<<'XML'
<catalog region="eu">
<offer id="1001" available="true">
<name>Keyboard</name>
<tag>office</tag>
<tag>usb</tag>
</offer>
</catalog>
XML;
$root = new XmlElement(FastXmlToArray::convert($xml));
$offer = $root->pull('offer')->current();
echo $root->name() . PHP_EOL; // catalog
echo $root->get('region') . PHP_EOL; // eu
echo ($root->hasElement('offer') ? 'yes' : 'no') . PHP_EOL; // yes
foreach ($offer->attributes() as $attribute) {
echo $attribute->name() . '=' . $attribute->value() . PHP_EOL;
}
$tagValues = array_map(
static fn (XmlElement $tag): string => $tag->value(),
$offer->elements('tag')
);
var_export($tagValues);
$snapshot = $offer->serialize();
$restored = new XmlElement($snapshot);
echo PHP_EOL;
echo $restored->get('id') . PHP_EOL; // 1001
Output:
catalog
eu
yes
id=1001
available=true
array (
0 => 'office',
1 => 'usb',
)
1001
XmlConverterCustom key names for one-shot conversion.
use SbWereWolf\XmlNavigator\Conversion\XmlConverter;
$converter = new XmlConverter(
val: 'value',
attr: 'attributes',
name: 'name',
seq: 'children',
);
$hierarchy = $converter->toHierarchyOfElements(
'<price currency="USD">129.90</price>'
);
var_export($hierarchy);
Output:
array (
'name' => 'price',
'value' => '129.90',
'attributes' =>
array (
'currency' => 'USD',
),
)
FastXmlToArray::prettyPrint()Readable output for application code and JSON.
use SbWereWolf\XmlNavigator\Conversion\FastXmlToArray;
$xml = <<<'XML'
<feed generated_at="2026-03-28T09:00:00Z">
<offer id="206111" available="true">
<name>USB-C Dock</name>
<price currency="USD">129.90</price>
<picture>https://cdn.example.test/1.jpg</picture>
<picture>https://cdn.example.test/2.jpg</picture>
</offer>
</feed>
XML;
$result = FastXmlToArray::prettyPrint($xml);
echo json_encode(
$result,
JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES
);
Output:
{
"feed": {
"@attributes": {
"generated_at": "2026-03-28T09:00:00Z"
},
"offer": {
"@attributes": {
"id": "206111",
"available": "true"
},
"name": "USB-C Dock",
"price": {
"@value": "129.90",
"@attributes": {
"currency": "USD"
}
},
"picture": [
"https://cdn.example.test/1.jpg",
"https://cdn.example.test/2.jpg"
]
}
}
}
FastXmlParser::extractPrettyPrint()Readable streaming output when you want JSON-like arrays directly.
use SbWereWolf\XmlNavigator\Parsing\FastXmlParser;
$uri = tempnam(sys_get_temp_dir(), 'xml-extract-kit-');
file_put_contents($uri, <<<'XML'
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<offer id="1">
<name>Keyboard</name>
<price>49.90</price>
</offer>
<service id="s-1">
<name>Warranty</name>
</service>
<offer id="2">
<name>Mouse</name>
<price>19.90</price>
</offer>
</catalog>
XML);
$reader = XMLReader::open($uri);
if ($reader === false) {
throw new RuntimeException('Cannot open XML file.');
}
$offers = FastXmlParser::extractPrettyPrint(
$reader,
static fn (XMLReader $cursor): bool => $cursor->name === 'offer'
);
foreach ($offers as $offer) {
echo json_encode($offer, JSON_PRETTY_PRINT) . PHP_EOL;
}
$reader->close();
unlink($uri);
When you already control the XMLReader cursor, the low-level
composers can serialize the current element directly.
use SbWereWolf\XmlNavigator\Extraction\HierarchyComposer;
use SbWereWolf\XmlNavigator\Extraction\PrettyPrintComposer;
$reader = XMLReader::XML(
'<price currency="USD">129.90</price>'
);
$hierarchy = HierarchyComposer::compose($reader);
$reader->close();
$reader = XMLReader::XML(
'<price currency="USD">129.90</price>'
);
$pretty = PrettyPrintComposer::compose($reader);
$reader->close();
var_export($hierarchy);
echo PHP_EOL;
var_export($pretty);