Here is my XML code:
<?xml version="1.0" encoding="UTF-8"?>
<file>
<header>
<information>Example information</information>
<agency>[email protected]</agency>
<date>2025-03-19 16:13:44</date>
<version>0.4</version>
<path>[email protected]</path>
<value>full</value>
</header>
<offers_list>
<department tab="local" type="sell">
<offert>
<param name="id">445/443/TS</param>
<location>
<area level="1">UK</area>
<area level="2">ON</area>
<area level="3">PIN</area>
<area level="4">As</area>
<area level="5">Ord</area>
</location>
<price currency="USD">1059000.00</price>
<n_geo_y>51.1894791</n_geo_y>
<n_geo_x>19.9072292</n_geo_x>
<street>Example</street>
</offert>
</department>
</offers_list>
</file>
and I'm trying to convert this XML text to array in that way:
$xml_string = file_get_contents($path.'file_xml.xml');
$xml = simplexml_load_string($xml_string, null, LIBXML_NOCDATA);
$xml = json_decode(json_encode($xml), true);
var_dump($xml);
Result:
array(2) {
["header"]=>
array(6) {
["information"]=>
string(19) "Example information"
["agency"]=>
string(9) "[email protected]"
["date"]=>
string(19) "2025-03-19 16:13:44"
["version"]=>
string(3) "0.4"
["path"]=>
string(12) "[email protected]"
["value"]=>
string(4) "full"
}
["offers_list"]=>
array(1) {
["department"]=>
array(2) {
["@attributes"]=>
array(2) {
["tab"]=>
string(5) "local"
["type"]=>
string(4) "sell"
}
["offert"]=>
array(6) {
["param"]=>
string(10) "445/443/TS"
["location"]=>
array(1) {
["area"]=>
array(5) {
[0]=>
string(2) "UK"
[1]=>
string(2) "ON"
[2]=>
string(3) "PIN"
[3]=>
string(2) "As"
[4]=>
string(3) "Ord"
}
}
["price"]=>
string(10) "1059000.00"
["n_geo_y"]=>
string(10) "51.1894791"
["n_geo_x"]=>
string(10) "19.9072292"
["street"]=>
string(7) "Example"
}
}
}
}
Finally, I got array but not complete. For example, I can't find this part of XML code:
< param name="id">445/443/TS
As result, I can't find attributes name with value like id.
Is it possible to convert full XML code to array in PHP?
Here is my XML code:
<?xml version="1.0" encoding="UTF-8"?>
<file>
<header>
<information>Example information</information>
<agency>[email protected]</agency>
<date>2025-03-19 16:13:44</date>
<version>0.4</version>
<path>[email protected]</path>
<value>full</value>
</header>
<offers_list>
<department tab="local" type="sell">
<offert>
<param name="id">445/443/TS</param>
<location>
<area level="1">UK</area>
<area level="2">ON</area>
<area level="3">PIN</area>
<area level="4">As</area>
<area level="5">Ord</area>
</location>
<price currency="USD">1059000.00</price>
<n_geo_y>51.1894791</n_geo_y>
<n_geo_x>19.9072292</n_geo_x>
<street>Example</street>
</offert>
</department>
</offers_list>
</file>
and I'm trying to convert this XML text to array in that way:
$xml_string = file_get_contents($path.'file_xml.xml');
$xml = simplexml_load_string($xml_string, null, LIBXML_NOCDATA);
$xml = json_decode(json_encode($xml), true);
var_dump($xml);
Result:
array(2) {
["header"]=>
array(6) {
["information"]=>
string(19) "Example information"
["agency"]=>
string(9) "[email protected]"
["date"]=>
string(19) "2025-03-19 16:13:44"
["version"]=>
string(3) "0.4"
["path"]=>
string(12) "[email protected]"
["value"]=>
string(4) "full"
}
["offers_list"]=>
array(1) {
["department"]=>
array(2) {
["@attributes"]=>
array(2) {
["tab"]=>
string(5) "local"
["type"]=>
string(4) "sell"
}
["offert"]=>
array(6) {
["param"]=>
string(10) "445/443/TS"
["location"]=>
array(1) {
["area"]=>
array(5) {
[0]=>
string(2) "UK"
[1]=>
string(2) "ON"
[2]=>
string(3) "PIN"
[3]=>
string(2) "As"
[4]=>
string(3) "Ord"
}
}
["price"]=>
string(10) "1059000.00"
["n_geo_y"]=>
string(10) "51.1894791"
["n_geo_x"]=>
string(10) "19.9072292"
["street"]=>
string(7) "Example"
}
}
}
}
Finally, I got array but not complete. For example, I can't find this part of XML code:
< param name="id">445/443/TS
As result, I can't find attributes name with value like id.
Is it possible to convert full XML code to array in PHP?
Share Improve this question edited Mar 22 at 0:56 hakre 198k55 gold badges449 silver badges855 bronze badges Recognized by PHP Collective asked Mar 21 at 18:37 user3022527user3022527 2,2082 gold badges16 silver badges12 bronze badges 3 |2 Answers
Reset to default 2Is it possible to convert full XML code to array in PHP?
Yes, it is, but mind that SimpleXMLElement already provides ArrayAccess so there is normally no need to do that as it has already been implemented. And for recursive traversal there is SimpleXMLIterator and RecursiveIteratorIterator.
And for SimpleXML to JSON there is a three-part series on my blog.
It is a bit dated but towards the end it is discussing writing custom replacers via JsonSerializable.
As outlined, when we go more towards the leaf-nodes, SimpleXMLElement does some common tree normalization and therefore tends to shortcut attributes from time to time. Or even element names.
The following is an example that merges attributes onto the object itself and puts the node-text on a property named as the element if necessary then. Only as a last resort creates tagged objects. That keeps the output dense:
$sxml = new class ($xmlString) extends SimpleXMLElement implements JsonSerializable
{
public function jsonSerialize(): mixed
{
$name = $this->getName();
$attributes = iterator_to_array($this->attributes());
$count = $this->count();
$named = iterator_to_array($this);
$names = count($named);
$list = iterator_to_array($this, false);
return match (true)
{
!$attributes => match (true)
{
!$count => (string)$this,
1 === $count,
$names === $count => $named,
1 === $names => $list,
default => array_map(fn($tag) => [$tag->getName() => $tag], $list)
},
!$count => $attributes + [$name => (string)$this],
1 === $count => $attributes + $named,
default => $this,
};
}
};
echo json_encode($sxml, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES), "\n";
{
"header": {
"information": "Example information",
"agency": "[email protected]",
"date": "2025-03-19 16:13:44",
"version": "0.4",
"path": "[email protected]",
"value": "full"
},
"offers_list": {
"department": {
"tab": "local",
"type": "sell",
"offert": {
"param": {
"name": "id",
"param": "445/443/TS"
},
"location": [
{
"level": "1",
"area": "UK"
},
{
"level": "2",
"area": "ON"
},
{
"level": "3",
"area": "PIN"
},
{
"level": "4",
"area": "As"
},
{
"level": "5",
"area": "Ord"
}
],
"price": {
"currency": "USD",
"price": "1059000.00"
},
"n_geo_y": "51.1894791",
"n_geo_x": "19.9072292",
"street": "Example"
}
}
}
}
Your XML-to-array conversion is losing attributes like name="id" because simplexml_load_string with json_encode/decode flattens them awkwardly. The param node’s name attribute gets dropped, and area levels turn into a numeric array. To grab everything, tweak your approach with SimpleXMLElement directly:
$xml_string = file_get_contents($path . 'file_xml.xml', LIBXML_NOCDATA);
$xml = simplexml_load_string($xml_string, null, LIBXML_NOCDATA);
$result = [];
foreach ($xml->children() as $node) {
$result[$node->getName()] = json_decode(json_encode($node), true);
// Preserve attributes manually
foreach ($node->xpath('.//*[@name]') as $attrNode) {
$name = (string)$attrNode['name'];
$result[$node->getName()]['offert']['param'] = [
'value' => (string)$attrNode,
'attributes' => ['name' => $name]
];
}
}
var_dump($result);
This keeps the name="id" under param as ['param']['attributes']['name'] => 'id', and the value 445/443/TS as ['param']['value']. The area levels stay intact too—just access them under location. It’s not perfect (you might need to loop deeper for nested attributes), but it’s closer to the full XML structure you want!
var_dump(simplexml_load_string($xml_string, null, LIBXML_NOCDATA))
. Finally the problem is the same. I got an objects of this XML file but I still can't find attributes: name and id. – user3022527 Commented Mar 21 at 18:54var_dump
invokes__debugInfo
or the internal equivalent, and is used as the name implies, for debugging, and I would not rely on it for normal daily code. You'll also find problems with namespaces, too. As noted in what I linked to, as well as an internals thread, your best best is to walk the data and create the structure that you think makes the most sense. Alternatively, I wouldn't be surprised if someone has made a library to do this, too. – Chris Haas Commented Mar 21 at 19:14