Posted at

simplexml_load_file(simplexml_load_string) を配列に変換する

More than 3 years have passed since last update.

simplexml_load_file()

simplexml_load_string()


json_encode()を使って変換する

たいていはこれで解決

PHP convert XML to JSON

$xml = simplexml_load_string($xml_string);

$json = json_encode($xml);
$array = json_decode($json,TRUE);

json_decode()を使い、第2引数(戻り値を連想配列にするかどうか)をtrueにする


arrayへのキャストを使って変換する

子要素がないとき限定

floatingdays: PHPの SimpleXMLを配列に変換する

arrayキャストだけでも変換できる

$xml = '<?xml version="1.0" ?>

<root>
<test>TEST1</test>
<test>TEST2</test>
<attr>WHY?</attr>
</root>'
;

$sx = simplexml_load_string($xml);
var_dump((array)$sx);

子要素があると

$xml = '<?xml version="1.0" ?>

<root>
<parent>
<child>MUSUKO</child>
</parent>
<attr foo="FOO" bar="BAR" />
</root>'
;

$sx = simplexml_load_string($xml);
var_dump((array)$sx);

出力結果

arrayへのキャストではすべて配列にならない

object(...)となっている箇所は配列ではなくオブジェクトを表す

array(2) {

["parent"]=>
object(SimpleXMLElement)#2 (1) {
["child"]=>
string(6) "MUSUKO"
}
["attr"]=>
object(SimpleXMLElement)#3 (1) {
["@attributes"]=>
array(2) {
["foo"]=>
string(3) "FOO"
["bar"]=>
string(3) "BAR"
}
}
}

オブジェクトがあると参照が特殊になる

// <child>MUSUKO</child> の MUSUKO

echo $sx['parent']->child;
// <attr foo="FOO" の FOO
echo $sx['attr']->attributes()->foo;

オブジェクトが返るので文字列にしたいときはキャストする必要がある

$child = (string)$sx->parent->child;

json_decode()を使うと

$xml = '<?xml version="1.0" ?>

<root>
<parent>
<child>MUSUKO</child>
</parent>
<attr foo="FOO" bar="BAR" />
</root>'
;

$sx = simplexml_load_string($xml);
var_dump(json_decode(json_encode($sx), true));

出力結果

array(2) {

["parent"]=>
array(1) {
["child"]=>
string(6) "MUSUKO"
}
["attr"]=>
array(1) {
["@attributes"]=>
array(2) {
["foo"]=>
string(3) "FOO"
["bar"]=>
string(3) "BAR"
}
}
}

ただし、属性とテキストノードの両方がある要素の属性(下記の例ではattr要素のtrouble="MISSING")が無視される

$xml = '<?xml version="1.0" ?>

<root>
<attr trouble="MISSING">WHY?</attr>
</root>'
;

$sx = simplexml_load_string($xml);
var_dump(json_decode(json_encode($sx), true));

出力結果

array(1) {

["attr"]=>
string(4) "WHY?"
}


再帰呼び出しを使って変換する

変換元のXML

$xml = '<parent>

<child>mmm</child>
<child2 id="1">
<grandchild row="0">
<great-grandchild country="US" currency="USD"/>
</grandchild>
<grandchild row="1">
<great-grandchild country="JP" currency="JPY"/>
</grandchild>
</child2>
</parent>';


単純に変換する

$sx = simplexml_load_string($xml);

var_dump($sx);

出力結果

object(SimpleXMLElement)#1 (2) {

["child"]=>
string(3) "mmm"
["child2"]=>
object(SimpleXMLElement)#2 (2) {
["@attributes"]=>
array(1) {
["id"]=>
string(1) "1"
}
["grandchild"]=>
array(2) {
[0]=>
object(SimpleXMLElement)#3 (2) {
["@attributes"]=>
array(1) {
["row"]=>
string(1) "0"
}
["great-grandchild"]=>
object(SimpleXMLElement)#5 (1) {
["@attributes"]=>
array(2) {
["country"]=>
string(2) "US"
["currency"]=>
string(3) "USD"
}
}
}
[1]=>
object(SimpleXMLElement)#4 (2) {
["@attributes"]=>
array(1) {
["row"]=>
string(1) "1"
}
["great-grandchild"]=>
object(SimpleXMLElement)#6 (1) {
["@attributes"]=>
array(2) {
["country"]=>
string(2) "JP"
["currency"]=>
string(3) "JPY"
}
}
}
}
}
}


(備考) 属性値を取得する

// <child2 id="1">の 1

echo $sx->child2->attributes()->id ;
// <great-grandchild country="US" currency="USD"/>の US
echo $sx->child2->grandchild[0]->{'great-grandchild'}->attributes()->country;


objectを配列へ変換する

Converting a SimpleXML Object to an Array [closed]

/**

* function xml2array
*
* This function is part of the PHP manual.
*
* The PHP manual text and comments are covered by the Creative Commons
* Attribution 3.0 License, copyright (c) the PHP Documentation Group
*
* @author k dot antczak at livedata dot pl
* @date 2011-04-22 06:08 UTC
* @link http://www.php.net/manual/en/ref.simplexml.php#103617
* @license http://www.php.net/license/index.php#doc-lic
* @license http://creativecommons.org/licenses/by/3.0/
* @license CC-BY-3.0 <http://spdx.org/licenses/CC-BY-3.0>
*/

function xml2array ( $xmlObject, $out = array () )
{
foreach ( (array) $xmlObject as $index => $node )
$out[$index] = ( is_object ( $node ) ) ? xml2array ( $node ) : $node;

return $out;
}

$sx = xml2array(simplexml_load_string($xml));
var_dump($sx);

出力結果

配列内のオブジェクトが変換されない

array(2) {

["child"]=>
string(3) "mmm"
["child2"]=>
array(2) {
["@attributes"]=>
array(1) {
["id"]=>
string(1) "1"
}
["grandchild"]=>
array(2) {
[0]=>
object(SimpleXMLElement)#4 (2) {
["@attributes"]=>
array(1) {
["row"]=>
string(1) "0"
}
["great-grandchild"]=>
object(SimpleXMLElement)#3 (1) {
["@attributes"]=>
array(2) {
["country"]=>
string(2) "US"
["currency"]=>
string(3) "USD"
}
}
}
[1]=>
object(SimpleXMLElement)#6 (2) {
["@attributes"]=>
array(1) {
["row"]=>
string(1) "1"
}
["great-grandchild"]=>
object(SimpleXMLElement)#5 (1) {
["@attributes"]=>
array(2) {
["country"]=>
string(2) "JP"
["currency"]=>
string(3) "JPY"
}
}
}
}
}
}


配列内のobjectも変換する

上記xmlArrayのforeach{...}部分

$out[$index] = ( is_object ( $node ) ) ? xml2array ( $node ) : $node;

$out[$index] = ( is_object ( $node ) || is_array ( $node ) ) ? xml2array ( $node ) : $node;

出力結果

array(2) {

["child"]=>
string(3) "mmm"
["child2"]=>
array(2) {
["@attributes"]=>
array(1) {
["id"]=>
string(1) "1"
}
["grandchild"]=>
array(2) {
[0]=>
array(2) {
["@attributes"]=>
array(1) {
["row"]=>
string(1) "0"
}
["great-grandchild"]=>
array(1) {
["@attributes"]=>
array(2) {
["country"]=>
string(2) "US"
["currency"]=>
string(3) "USD"
}
}
}
[1]=>
array(2) {
["@attributes"]=>
array(1) {
["row"]=>
string(1) "1"
}
["great-grandchild"]=>
array(1) {
["@attributes"]=>
array(2) {
["country"]=>
string(2) "JP"
["currency"]=>
string(3) "JPY"
}
}
}
}
}
}

@attributesを除くのはあきらめる


Converting a SimpleXML object to an array

のxmlToArrayを使用すると

$xml = '<?xml version="1.0" ?>

<root>
<parent>
<child>MUSUKO</child>
</parent>
<attr foo="FOO" bar="BAR" />
</root>'
;
$sx = simplexml_load_string($xml);
var_dump(xmlToArray($sx));

出力結果

'@attributes'はなくなるが検証が大変そう

array(1) {

["root"]=>
array(2) {
["parent"]=>
array(1) {
["child"]=>
string(6) "MUSUKO"
}
["attr"]=>
array(2) {
["attributes"]=>
array(2) {
["foo"]=>
string(3) "FOO"
["bar"]=>
string(3) "BAR"
}
["value"]=>
string(0) ""
}
}
}


namespaceがあるXMLの変換

<?xml version="1.0" encoding="UTF-8" ?>

<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0">
<channel>
<title>LIG</title>
<item>
<title>LIG Item01</title>
<g:id>91954</g:id>
<g:name>LIG Name01</g:name>
</item>
</channel>
</rss>


一手間必要。PHPでのSimpleXML関数のパース処理