Reputation: 418
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..
Upvotes: 8
Views: 52597
Reputation: 1725
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);
Upvotes: 3
Reputation: 3665
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:
And this:
Hope that helps... :)
Upvotes: 20
Reputation: 2710
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
Upvotes: 9
Reputation: 173542
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}";
}
}
Upvotes: 9