こちらの関数を使用すると簡単に取得できます。
が、次の <dddd>タグのような attributes が取得できません。( Id="id:pass" が無視される)
<eeee>タグ内の attributes は取得できます。
$xml = <<< DOC_END
<aaaa Version="1.0">
<bbb>
<cccc>
<dddd Id="id:pass">テスト</dddd>
<eeee name="hearaman" age="24" />
</cccc>
</bbb>
</aaaa>
DOC_END;
function xml2array($xml){
$xml = preg_replace('/(<\/?)\w+:([^>]*>)/', '$1$2', $xml); //get rid of namespaces
$xml = simplexml_load_string($xml);
return json_decode(json_encode($xml),true); //use built-in stuff
}
結果
Array
(
[@attributes] => Array
(
[Version] => 1.0
)
[bbb] => Array
(
[cccc] => Array
(
[dddd] => テスト
[eeee] => Array
(
[@attributes] => Array
(
[name] => hearaman
[age] => 24
)
)
)
)
)
完璧に取得したい場合はこちらがおすすめです。
function XMLtoArray($xml) {
$previous_value = libxml_use_internal_errors(true);
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->preserveWhiteSpace = false;
$dom->loadXml($xml);
libxml_use_internal_errors($previous_value);
if (libxml_get_errors()) {
return [];
}
return DOMtoArray($dom);
}
function DOMtoArray($root) {
$result = array();
if ($root->hasAttributes()) {
$attrs = $root->attributes;
foreach ($attrs as $attr) {
$result['@attributes'][$attr->name] = $attr->value;
}
}
if ($root->hasChildNodes()) {
$children = $root->childNodes;
if ($children->length == 1) {
$child = $children->item(0);
if (in_array($child->nodeType,[XML_TEXT_NODE,XML_CDATA_SECTION_NODE])) {
$result['_value'] = $child->nodeValue;
return count($result) == 1
? $result['_value']
: $result;
}
}
$groups = array();
foreach ($children as $child) {
if (!isset($result[$child->nodeName])) {
$result[$child->nodeName] = DOMtoArray($child);
} else {
if (!isset($groups[$child->nodeName])) {
$result[$child->nodeName] = array($result[$child->nodeName]);
$groups[$child->nodeName] = 1;
}
$result[$child->nodeName][] = DOMtoArray($child);
}
}
}
return $result;
}
結果
Array
(
[aaaa] => Array
(
[@attributes] => Array
(
[Version] => 1.0
)
[bbb] => Array
(
[cccc] => Array
(
[dddd] => Array
(
[@attributes] => Array
(
[Id] => id:pass
)
[_value] => テスト
)
[eeee] => Array
(
[@attributes] => Array
(
[name] => hearaman
[age] => 24
)
)
)
)
)
)
引用元 : https://goo.gl/Ko7fwC
名前空間の名前が付いてくるのが邪魔な場合は変換前に次の1行を噛ませて名前空間を削除しておきましょう。
$xml = preg_replace('/(<\/?)\w+:([^>]*>)/', '$1$2', $xml); //get rid of namespaces
よくネットで見かけるやり方です。通常これでも問題ないのですが、 <ns2:ItemDimensions> のようなネーム空間を持つXMLを変換できない時があります。
$xml = simplexml_load_string($html);
$xml_array = json_decode( json_encode( $xml ), TRUE );
返される xml が x-sjis-cp932 エンコーディングの場合エラーとなるので、次のように変換する。
$data = mb_convert_encoding($data,"UTF-8");
$data = str_replace("x-sjis-cp932","UTF-8",$data);