Изменяя xpath, как и другие, я пришел к такому выводу. Он работает с одной вспомогательной функцией для переформатирования каждого узла результатов xpath и использует array_reduce
для перебора результата. Затем он возвращает преобразованный результат ( Демо ):
$xml = new SimpleXMLElement($xmlstr);
$elements = array_reduce(
$xml->xpath('//OSes/*/*'),
function($v, $w) {
$w = array_values((array) $w); // convert result to array
foreach($w as &$d) $d = (array) $d; // convert inner elements to array
return array_merge($v, $w); // merge with existing
},
array() // empty elements at start
);
Выход:
Array
(
[0] => Array
(
[id] => centos5-32
[name] => CentOS 5 - 32 bit
[version] => 5
[architecture] => 32
[os] => centos
)
[1] => Array
(
[id] => centos5-64
[name] => CentOS 5 - 64 bit
[version] => 5
[architecture] => 64
[os] => centos
)
[2] => Array
(
[id] => centos6-32
[name] => CentOS 6 - 32 bit
[version] => 6
[architecture] => 32
[os] => centos
)
[3] => Array
(
[id] => centos6-64
[name] => CentOS 6 - 64 bit
[version] => 6
[architecture] => 64
[os] => centos
)
[4] => Array
(
[id] => ubuntu10-32
[name] => Ubuntu 10 - 32 bit
[version] => 10
[architecture] => 32
[os] => ubuntu
)
[5] => Array
(
[id] => ubuntu10-64
[name] => Ubuntu 10 - 64 bit
[version] => 10
[architecture] => 64
[os] => ubuntu
)
)
Я также выбрал преобразование исходного результата xpath в массив из двух уровней, каждый раз, когда на текущем уровне уже существует ключ, переместить текущую запись в новую запись ( Demo ):
try
{
$xml = new SimpleXMLElement($xmlstr);
$elements = array();
$curr = NULL;
foreach($xml->xpath('//id | //name | //version | //architecture | //os') as $record)
{
$key = $record->getName();
$value = (string) $record;
if (!$curr || array_key_exists($key, $curr)) {
unset($curr);
$curr = array();
$elements[] = &$curr;
}
$curr[$key] = $value;
}
unset($curr);
}
catch(Exception $e)
{
echo $e->getMessage();
}
Результат таков:
Array
(
[0] => Array
(
[id] => centos5-32
[name] => CentOS 5 - 32 bit
[version] => 5
[architecture] => 32
[os] => centos
)
[1] => Array
(
[id] => centos5-64
[name] => CentOS 5 - 64 bit
[version] => 5
[architecture] => 64
[os] => centos
)
[2] => Array
(
[id] => centos6-32
[name] => CentOS 6 - 32 bit
[version] => 6
[architecture] => 32
[os] => centos
)
[3] => Array
(
[id] => centos6-64
[name] => CentOS 6 - 64 bit
[version] => 6
[architecture] => 64
[os] => centos
)
[4] => Array
(
[id] => ubuntu10-32
[name] => Ubuntu 10 - 32 bit
[version] => 10
[architecture] => 32
[os] => ubuntu
)
[5] => Array
(
[id] => ubuntu10-64
[name] => Ubuntu 10 - 64 bit
[version] => 10
[architecture] => 64
[os] => ubuntu
)
)