Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XML to Array? [PHP]

Tags:

arrays

php

xml

Well I been having issues changing an xml back into an array....It would be simple if each xml followed the same format but every XML is different with the exception of the <Formula> tag, formulaname and movespeed ex:

<Formula>
<formulaname>Basic</formulaname>
<movespeed>1</movespeed>
<str>4</str>
<dex>3</dex>
<int>1</int>
<will>2</will>
</Formula>

or

<Formula>
<formulaname>Basic</formulaname>
<movespeed>1</movespeed>
<box>4</box>
<chicken>3</chicken>
<ducks>1</ducks>
<cereal>2</cereal>
</Formula>

What I have tried:

$xml = simplexml_load_file("test.xml");
print_r($xml);

This actually prints something but I couldn't get past that or even echo it..

foreach($xml->text as $string) { 
  print_r($string);
  echo 'attributes: '. $string->attributes() .'<br />';
}

Didn't work, originally it's for strings but none of them are strings...

foreach ($xml->Formula as $element) {
  foreach($element as $key => $val) {
   echo "{$key}: {$val}";
  }

Didn't work either, I needed something like this to work so I can use the values from the array without knowing what exactly the value will be called..

like image 385
Ginzo Milani Avatar asked Aug 27 '12 19:08

Ginzo Milani


People also ask

How get data from XML URL in PHP?

$url = 'http://www.example.com'; $xml = simpleXML_load_file($url,"SimpleXMLElement",LIBXML_NOCDATA); $url can be php file, as long as the file generate xml format data as output.

Can PHP read XML?

The PHP simplexml_load_file() function is used to read XML data from a file.


4 Answers

This is your best bet, and it should eliminate all the SimpleXMLElement objects and instead give you nothing but arrays:

$xml = simplexml_load_file("test.xml");
$xml_array = unserialize(serialize(json_decode(json_encode((array) $xml), 1)));
print_r($xml_array);

Makes the difference between this:


Array with SimpleXMLElement objects


And this:


All arrays - no mixture with SimpleXMLElement objects


Hope that helps... :)

like image 113
jerdiggity Avatar answered Oct 05 '22 14:10

jerdiggity


You can't access children by using a foreach on the node itself, you need to use .children():

$s =<<<EOS
<root>
<Formula>
<formulaname>Basic</formulaname>
<movespeed>1</movespeed>
<box>4</box>
<chicken>3</chicken>
<ducks>1</ducks>
<cereal>2</cereal>
</Formula>
</root>
EOS;

$xml = simplexml_load_string($s);

foreach ($xml->Formula as $element) {
    foreach($element->children() as $key => $val) {
        echo "{$key}: {$val}";
    }
}
like image 27
Ja͢ck Avatar answered Oct 05 '22 15:10

Ja͢ck


for your example this code is enough:

$xml = simplexml_load_file('formula.xml');
$arr = (array) $xml;
var_dump($arr);

and your xml goes into array
formula.xml contains your xml

like image 41
mrok Avatar answered Oct 05 '22 14:10

mrok


If you have cdata and and attributes in the same node, using the methods above will omit the attributes.

try using this method:

function xml2array($xmlObject, $out = [])
{
    foreach($xmlObject->attributes() as $attr => $val)
        $out['@attributes'][$attr] = (string)$val;

    $has_childs = false;
    foreach($xmlObject as $index => $node)
    {
        $has_childs = true;
        $out[$index][] = xml2array($node);
    }
    if (!$has_childs && $val = (string)$xmlObject)
        $out['@value'] = $val;

    foreach ($out as $key => $vals)
    {
        if (is_array($vals) && count($vals) === 1 && array_key_exists(0, $vals))
            $out[$key] = $vals[0];
    }
    return $out;
}
$xml = simplexml_load_string($xml_string, 'SimpleXMLElement', LIBXML_NOCDATA);
$arr = xml2array($xml);
like image 32
Roey Avatar answered Oct 05 '22 15:10

Roey