Reputation: 2802
There are noumerous questions on converting XML to array, and simpliest method is as follows:
$data = unserialize(serialize(json_decode(json_encode((array)simplexml_load_string($dataXml)), 1)));
However, I cant get attributes names using this approach, and could not find any questions on SO, explaining how to do it.
Here is part of XML that I have:
<Object>
<attribute name="Surname">Ярош</attribute>
<attribute name="Name">Анна</attribute>
<attribute name="Middle name">Григорьевна</attribute>
<attribute name="Position">Торговый представитель розничных продаж</attribute>
<attribute name="City">BAIKALSEA Company Иркутск</attribute>
<attribute name="Division">Отдел продаж</attribute>
<attribute name="Department">Продажи</attribute>
<attribute name="Email">[email protected]</attribute>
<attribute name="MobPhone">79149274726</attribute>
<attribute name="WorkPhone">-</attribute>
<attribute name="Manager">Нет</attribute>
<attribute name="HonoredWorker">Нет</attribute>
<attribute name="Login">[email protected]</attribute>
<attribute name="Character">Пользователь</attribute>
</Object>
And here is what I get converting it with encode/decode and simpleXml:
As you can see 'name' attribute and its value is lost. I need those name
attributes and their values as well. Pls any help appreciated.
Upvotes: 0
Views: 3030
Reputation: 97688
I think you have fundamentally the wrong approach. Rather than trying to create one function that can express all possible contents of an XML document in one array, use the APIs provided by SimpleXML to extract the data you need for your particular task.
Given your example input, a useful output might be an associative array of key-value pairs, like this:
Array (
[Surname] => Ярош
[Name] => Анна
[Middle name] => Григорьевна
[Position] => Торговый представитель розничных продаж
[City] => BAIKALSEA Company Иркутск
[Division] => Отдел продаж
[Department] => Продажи
[Email] => [email protected]
[MobPhone] => 79149274726
[WorkPhone] => -
[Manager] => Нет
[HonoredWorker] => Нет
[Login] => [email protected]
[Character] => Пользователь
)
Which can be achieved with a simple loop over a SimpleXML element:
$sx = simplexml_load_string($xml);
$parsed_attributes = [];
foreach ( $sx->attribute as $attribute_element ) {
$parsed_attributes[ (string)$attribute_element['name'] ] = (string)$attribute_element;
}
print_r($parsed_attributes);
If you don't know in this part of the application how you're going to use the data, keep it as a SimpleXMLElement, and give the rest of your code the power of that API. If you want to store it to use later, use ->asXML()
and store it back in XML form.
Upvotes: 0
Reputation: 2802
Ok, I finally found function, that converts XML to object, preserving namespaces, attributes, childs and so on:
function xmlObjToArr($obj) {
$namespace = $obj->getDocNamespaces(true);
$namespace[NULL] = NULL;
$children = array();
$attributes = array();
$name = strtolower((string)$obj->getName());
$text = trim((string)$obj);
if( strlen($text) <= 0 ) {
$text = NULL;
}
// get info for all namespaces
if(is_object($obj)) {
foreach( $namespace as $ns=>$nsUrl ) {
// atributes
$objAttributes = $obj->attributes($ns, true);
foreach( $objAttributes as $attributeName => $attributeValue ) {
$attribName = strtolower(trim((string)$attributeName));
$attribVal = trim((string)$attributeValue);
if (!empty($ns)) {
$attribName = $ns . ':' . $attribName;
}
$attributes[$attribName] = $attribVal;
}
// children
$objChildren = $obj->children($ns, true);
foreach( $objChildren as $childName=>$child ) {
$childName = strtolower((string)$childName);
if( !empty($ns) ) {
$childName = $ns.':'.$childName;
}
$children[$childName][] = xmlObjToArr($child);
}
}
}
return array(
'name'=>$name,
'text'=>$text,
'attributes'=>$attributes,
'children'=>$children
);
}
Upvotes: 1