Xml to Array is a simple library to convert XML into PHP array.
The library consists in one namespace Susina\XmlToArray
and two classes:
Converter
: to convert an XML string into PHP arrayFileConverter
: to convert an XML file
Both classes expose the same public api:
- Susina\XmlToArray\Converter
convert(string $xmlToParse): array
to convert an xml string into an arrayconvertAndSave(string $xmlToParse, string $filename): void
to convert an xml string to an array and save it into a regular php file.
- Susina\XmlToArray\FileConverter
convert(string $xmlFile): array
to read an xml file and convert it into an arrayconvertAndSave(string $xmlFile, string $filename): void
to read an xml file and, convert it into an array and save it into a regular php file.
Install the library via composer:
composer require susina/xml-to-array
The library depends on three php extensions, usually installed by default:
- libxml
- simplexml
- dom
and Symfony Options Resolver component, that'll be install by composer.
Use the convert
method to parse an XML string. Let's get a look at the following example:
<?php declare(strict_types=1);
use Susina\XmlToArray\Converter;
$xmlString = "
<?xml version='1.0' standalone='yes'?>
<movies>
<movie>
<title>Star Wars</title>
<starred>True</starred>
<percentage>32.5</percentage>
</movie>
<movie>
<title>The Lord Of The Rings</title>
<starred>false</starred>
<percentage>30.7</percentage>
</movie>
</movies>
";
$converter = new Converter();
$array = $converter->convert($xmlString);
/*
* $array now contains the following array:
*
* [
* "movie" => [
* 0 => [
* "title" => "Star Wars",
* "starred" => true,
* "percentage" => 32.5
* ],
* 1 => [
* "title" => "The Lord Of The Rings",
* "starred" => false,
* "percentage" => 30.7
* ]
* ]
* ]
*/
Alternatively, you can use the static instantiator:
<?php declare(strict_types=1);
.....
$array = Converter::create()->convert($xmlString);
If you want to read and convert an xml file, you can play with FileConverter
class:
<?php declare(strict_types=1);
use Susina\XmlToArray\FileConverter;
$converter = new FileConverter();
$array = $converter->convert('/my_dir/my_file.xml');
and by using the static constructor:
<?php declare(strict_types=1);
$array = FileConverter::create()->convert('/my_dir/my_file.xml');
You can save the converted array into a regular formatted php file, that you can import in some other script by include PHP statement.
For example:
<?php declare(strict_types=1);
use Susina\XmlToArray\Converter;
$xmlString = "
<?xml version='1.0' standalone='yes'?>
<movies>
<movie>
<title>Star Wars</title>
<starred>True</starred>
<percentage>32.5</percentage>
</movie>
<movie>
<title>The Lord Of The Rings</title>
<starred>false</starred>
<percentage>30.7</percentage>
</movie>
</movies>
";
$converter = new Converter();
$converter->convertAndSave($xmlString, 'array_file.php');
The content of array_file.php
is the following:
<?php declare(strict_types=1);
/*
* This file is auto-generated by susina/xml-to-array library.
*/
return array (
'movie' =>
array (
0 =>
array (
'title' => 'Star Wars',
'starred' => true,
'percentage' => 32.5,
),
1 =>
array (
'title' => 'The Lord Of The Rings',
'starred' => false,
'percentage' => 30.7,
),
),
);
You can load your array via include
statement:
<?php declare(strict_types=1);
//Some instructions
$array = include('array_file.php');
Also FileConverter
class has its convertAndSave
method, which has the same behavior, but it accepts the name of the xml file to convert as first parameter:
<?php declare(strict_types=1);
...........
FileConverter::create()->convertAndSave($xmlFileName, 'array_file.php');
You can configure the converters by passing an associative array to the constructor, where the keys are the name of the option. The available options are the following:
- mergeAttributes: boolean, default true
- idAsKey: boolean, default true
- typesAsString: boolean, default false
- preserveFirstTag: boolean, default false
Default: true
When this option is set to true, the attributes of a tag are merged into the tag it self, otherwise they're saved into a @attribute
array, i.e.:
<?php declare(strict_types=1);
$xmlString = '
<?xml version="1.0" encoding="utf-8"?>
<config>
<logger name="defaultLogger">
<type>stream</type>
<path>/var/log/default.log</path>
<level>300</level>
</logger>
</config>
';
//mergeAttributes is true by default
$array = Converter::create()->convert($xmlString);
/*
* $array now contains the following array:
*
* [
* "logger" => [
* "name" => "defaultLogger",
* "type" => "stream",
* "path" => "/var/log/default.log"
* "level" => 300
* ]
* ]
*/
In the previous example, you can see that the name attribute is "merged" into logger array.
When this option is set to false, a @attribute array is created:
<?php declare(strict_types=1);
$xmlString = '
<?xml version="1.0" encoding="utf-8"?>
<config>
<logger name="defaultLogger">
<type>stream</type>
<path>/var/log/default.log</path>
<level>300</level>
</logger>
</config>
';
$array = Converter::create(['mergeAttributes' => false])->convert($xmlString);
/*
* $array now contains the following array:
*
* [
* "logger" => [
* "@attributes" => [
* "name" => "defaultLogger"
* ],
* "type" => "stream",
* "path" => "/var/log/default.log"
* "level" => 300
* ]
* ]
*/
Default: true
When this option is set to true, the value of an id attribute or tag is considered as the key of an associative array, i.e.:
<?php declare(strict_types=1);
$xmlString = "
<?xml version='1.0' standalone='yes'?>
<movies>
<movie>
<title>Star Wars</title>
<starred>True</starred>
<actor id=\"actorH\" name=\"Harrison Ford\" />
<actor id=\"actorM\" name=\"Mark Hamill\" />
<actor>
<id>actorC</id>
<name>Carrie Fisher</name>
</actor>
</movie>
</movies>";
//idAsKey is true by default
$array = Converter::create()->convert($xmlString);
/*
* $array now contains the following array:
*
* 'movie' => [
* 0 => [
* 'title' => 'Star Wars',
* 'starred' => true,
* 'actorH' => ['name' => 'Harrison Ford'],
* 'actorM' => ['name' => 'Mark Hamill'],
* 'actorC' => ['name' => 'Carrie Fisher']
* ]
* ]
*/
Otherwise, if you set this option to false no magic happens:
<?php declare(strict_types=1);
$xmlString = "
<?xml version='1.0' standalone='yes'?>
<movies>
<movie>
<title>Star Wars</title>
<starred>True</starred>
<actor id=\"actorH\" name=\"Harrison Ford\" />
<actor id=\"actorM\" name=\"Mark Hamill\" />
<actor>
<id>actorC</id>
<name>Carrie Fisher</name>
</actor>
</movie>
</movies>";
$converter = new Converter(['idAsKey' => false]);
$array = $converter->convert($xmlString);
/*
* $array now contains the following array:
*
* 'movie' => [
* 0 => [
* 'title' => 'Star Wars',
* 'starred' => true,
* 'actor' => [
* 0 => [
* 'id' => 'actorH',
* 'name' => 'Harrison Ford'
* ],
* 1 => [
* 'id' => 'actorM',
* 'name' => 'Mark Hamill'
* ],
* 2 => [
* 'id' => 'actorC',
* 'name' => 'Carrie Fisher'
* ]
* ]
* ]
* ]
*/
Default: false
The normal behavior of this library is to preserve all PHP types (boolean, numeric, null etc.). If typesAsString option is set to true all the values are considered strings:
<?php declare(strict_types=1);
use Susina\XmlToArray\Converter;
$xmlString = "
<?xml version='1.0' standalone='yes'?>
<movies>
<movie>
<title>Star Wars</title>
<starred>True</starred>
<percentage>32.5</percentage>
<views>589623</views>
</movie>
</movies>
";
// typesAsString is false by default
$array = Converter::create()->convert($xmlString);
/*
* $array now contains the following array:
*
* [
* "movie" => [
* 0 => [
* "title" => "Star Wars",
* "starred" => true,
* "percentage" => 32.5,
* "views" => 589623
* ],
* ]
* ]
*/
In the previous example, if you set the property to true, all values are strings:
<?php declare(strict_types=1);
use Susina\XmlToArray\Converter;
$xmlString = .......
$array = Converter::create(['typesAsString' => true])->convert($xmlString);
/*
* $array now contains the following array:
*
* [
* "movie" => [
* 0 => [
* "title" => "Star Wars",
* "starred" => 'True',
* "percentage" => '32.5'
* "views" => '589623'
* ],
* ]
* ]
*/
Default: false
If your xml document starts with a single tag, containing all the others, the first tag is not considered as part of the resulting array:
<?php declare(strict_types=1);
use Susina\XmlToArray\Converter;
$xmlString = "
<?xml version='1.0' standalone='yes'?>
<database>
<movie>
<title>Star Wars</title>
</movie>
<movie>
<title>The Lord Of The Rings</title>
</movie>
<movie>
<title>Spider-Man</title>
</movie>
</database>
";
// preserveFirstTag is false by default
$converter = new Converter();
$array = $converter->convert($xmlString);
/*
* $array now contains the following array:
*
* [
* "movie" => [
* 0 => [
* "title" => "Star Wars",
* ],
* 1 => [
* "title" => "The Lord Of The Rings",
* ],
* 2 => [
* "title" "Spider-Man"
* ]
* ]
* ]
*/
If you want to keep this tag as the first key of your array, set this option to true:
<?php declare(strict_types=1);
use Susina\XmlToArray\Converter;
$xmlString = .............
$converter = new Converter(['preserveFirstTag' => true]);
$array = $converter->convert($xmlString);
/*
* $array now contains the following array:
*
* [
* "database => [
* "movie" => [
* 0 => [
* "title" => "Star Wars",
* ],
* 1 => [
* "title" => "The Lord Of The Rings",
* ],
* 2 => [
* "title" "Spider-Man"
* ]
* ]
* ]
* ]
*/
If you find a bug or any other issue, please report it on Github.
Please, see CONTRIBUTING.md
This library is released under Apache-2.0 license.