LoginSignup
51
43

More than 5 years have passed since last update.

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

Posted at

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関数のパース処理

51
43
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
51
43