Consider the following XML:
<?xml version="1.0" encoding="UTF-8"?>
<OS>
<data>
<OSes>
<centos>
<v_5>
<i386>
<id>centos5-32</id>
<name>CentOS 5 - 32 bit</name>
<version>5</version>
<architecture>32</architecture>
<os>centos</os>
</i386>
<x86_64>
<id>centos5-64</id>
<name>CentOS 5 - 64 bit</name>
<version>5</version>
<architecture>64</architecture>
<os>centos</os>
</x86_64>
</v_5>
<v_6>
<i386>
<id>centos6-32</id>
<name>CentOS 6 - 32 bit</name>
<version>6</version>
<architecture>32</architecture>
<os>centos</os>
</i386>
<x86_64>
<id>centos6-64</id>
<name>CentOS 6 - 64 bit</name>
<version>6</version>
<architecture>64</architecture>
<os>centos</os>
</x86_64>
</v_6>
</centos>
<ubuntu>
<v_10>
<i386>
<id>ubuntu10-32</id>
<name>Ubuntu 10 - 32 bit</name>
<version>10</version>
<architecture>32</architecture>
<os>ubuntu</os>
</i386>
<amd64>
<id>ubuntu10-64</id>
<name>Ubuntu 10 - 64 bit</name>
<version>10</version>
<architecture>64</architecture>
<os>ubuntu</os>
</amd64>
</v_10>
</ubuntu>
</OSes>
</data>
</OS>
From the XML document above, I want to extract following 5 element node
<id>
<name>
<version>
<architecture>
<os>
And have them as a array. I tried doing the following:
<?php
require_once "xml.php";
try {
$xml = new SimpleXMLElement($xmlstr);
foreach($xml->xpath(' //id | //name | //version// | //architecture | //os ') as $record) {
echo $record;
}
} catch(Exception $e){
echo $e->getMessage();
}
the above code works but each record is an separate object. I want someone to consolidate all 5 elements nodes as one array element. something like this:
$osList = Array( [0] => Array(
["id"] => "<id>",
["name"] => "<name>",
["version"] => "<version>",
....
)
.....
);
syntax isn't correct but you get the idea. any idea how to do this?
Try this:
My result:
If you're using PHP >= 5.3 (ofcourse you are, why whouldn't you) you can omit the nasty tmp function definitions and use cool anonymous functions for the mapping:
By modifying the xpath as others suggested as well, I came to this conclusion. It works with one helper function to re-format each xpath result node and uses
array_reduce
to iterate over the result. It then returns the converted result (Demo):Output:
I also opted for converting the original xpath result into an array of two levels, each time within the current level a key already exists, move the current entry to a new entry (Demo):
Result is like this then:
this might help