This is what I got. And this is the solution which I expected.
http://outlandish.com/blog/xml-to-json/
Answer from Abhishek Sanghvi on Stack OverflowVideos
a more elegant way; it gives you the same results without using $attributes[ '@attributes' ] :
$attributes = current($element->attributes());
Don't directly read the '@attributes' property, that's for internal use. Anyway, attributes() can already be used as an array without needing to "convert" to a real array.
For example:
<?php
$xml = '<xml><test><a a="b" r="x" q="v" /></test><b/></xml>';
$x = new SimpleXMLElement(
attr = $x->test[0]->a[0]->attributes();
echo $attr['a']; // "b"
If you want it to be a "true" array, you're gonna have to loop:
$attrArray = array();
$attr = $x->test[0]->a[0]->attributes();
foreach($attr as
val){
$attrArray[(string)$key] = (string)$val;
}
easy!
$xml = simplexml_load_string($xmlstring, "SimpleXMLElement", LIBXML_NOCDATA);
$json = json_encode(
array = json_decode($json,TRUE);
Another option is the SimpleXML extension (I believe it comes standard with most php installs.)
http://php.net/manual/en/book.simplexml.php
The syntax looks something like this for your example
$xml = new SimpleXMLElement($xmlString);
echo $xml->bbb->cccc->dddd['Id'];
echo $xml->bbb->cccc->eeee['name'];
// or...........
foreach ($xml->bbb->cccc as $element) {
foreach($element as
val) {
echo "{$key}: {$val}";
}
}
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
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 =
attribName;
}
$attributes[$attribName] = $attribVal;
}
// children
$objChildren = $obj->children($ns, true);
foreach( $objChildren as $childName=>$child ) {
$childName = strtolower((string)$childName);
if( !empty($ns) ) {
$childName =
childName;
}
$children[$childName][] = xmlObjToArr($child);
}
}
}
return array(
'name'=>$name,
'text'=>$text,
'attributes'=>$attributes,
'children'=>$children
);
}
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(
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.
Something like this should work:
function XMLtoArray($xml) {
$xmlArray = array();
$dom = new DOMDocument;
$dom->load($xml);
$categories = $dom->getElementsByTagName("category");
foreach($categories as $category) {
$id = $category->getAttribute("id");
$xmlArray[$id] = $category->nodeValue;
}
return($xmlArray);
}
Then call the function like so:
$myArray = XMLtoArray("path/to/file.xml");
<?php
include ("htmlparser.php");
$string = '
<mapi>
<categoriesList>
<category id="310">Autres</category>
<category id="574">Bière</category>
<category id="495">Biscuits</category>
<category id="444">Bonbons</category>
<category id="435">Champagne</category>
<category id="371">Cidre</category>
<category id="215">Condiments</category>
<category id="8">Fruits</category>
<category id="445">Poissons</category>
<category id="578">Produits laitiers</category>
<category id="539">Spiritueux</category>
<category id="259">Viandes</category>
<category id="126">Vin</category>
</categoriesList>
</mapi>
';
$html = str_get_html($string);
foreach($html->find('category') as $element){
$array[] = $element -> innertext ;
}
echo '<pre>';
print_r($array);
?>
You need to download this library: http://simplehtmldom.sourceforge.net/manual.htm#section_dump