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

[simplexml_load_file()](http://php.net/manual/ja/function.simplexml-load-file.php)
[simplexml_load_string()](http://php.net/manual/ja/function.simplexml-load-string.php)

## json_encode()を使って変換する
たいていはこれで解決
[PHP convert XML to JSON](http://stackoverflow.com/questions/8830599/php-convert-xml-to-json)

```php
$xml = simplexml_load_string($xml_string);
$json = json_encode($xml);
$array = json_decode($json,TRUE);
```
`json_decode()`を使い、第2引数（戻り値を連想配列にするかどうか）をtrueにする


## arrayへのキャストを使って変換する
子要素がないとき限定

[floatingdays: PHPの SimpleXMLを配列に変換する](http://fdays.blogspot.jp/2011/03/php-simplexml.html)

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

```php
$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);
```

子要素があると

```php
$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(...)`となっている箇所は配列ではなくオブジェクトを表す

```text
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"
    }
  }
}
```

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

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

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

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

`json_decode()`を使うと

```php
$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));
```

**出力結果**

```text
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"）が無視される

```php
$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));
```

**出力結果**

```text
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>';
```

### 単純に変換する

```php
$sx = simplexml_load_string($xml);
var_dump($sx);
```

**出力結果**

```text
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"
          }
        }
      }
    }
  }
}
```

> ##### **（備考）** 属性値を取得する

> ```php
// <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]](http://stackoverflow.com/questions/6167279/converting-a-simplexml-object-to-an-array)

```php
/**
 * 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);
```

**出力結果**
配列内のオブジェクトが変換されない

```text
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{...}`部分

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

を

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

**出力結果**

```text
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](http://milesj.me/blog/read/simplexml-to-array)
のxmlToArrayを使用すると

> ```php
$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'`はなくなるが検証が大変そう

> ```text
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関数のパース処理](http://liginc.co.jp/programmer/archives/5317)