我想把下面的XML转换成PHP数组。有什么建议吗?
<aaaa Version="1.0">
<bbb>
<cccc>
<dddd Id="id:pass" />
<eeee name="hearaman" age="24" />
</cccc>
</bbb>
</aaaa>
我想把下面的XML转换成PHP数组。有什么建议吗?
<aaaa Version="1.0">
<bbb>
<cccc>
<dddd Id="id:pass" />
<eeee name="hearaman" age="24" />
</cccc>
</bbb>
</aaaa>
当前回答
参见https://github.com/gaarf/XML-string-to-PHP-array/blob/master/xmlstr_to_array.php
<?php
/**
* convert xml string to php array - useful to get a serializable value
*
* @param string $xmlstr
* @return array
*
* @author Adrien aka Gaarf & contributors
* @see http://gaarf.info/2009/08/13/xml-string-to-php-array/
*/
function xmlstr_to_array($xmlstr) {
$doc = new DOMDocument();
$doc->loadXML($xmlstr);
$root = $doc->documentElement;
$output = domnode_to_array($root);
$output['@root'] = $root->tagName;
return $output;
}
function domnode_to_array($node) {
$output = array();
switch ($node->nodeType) {
case XML_CDATA_SECTION_NODE:
case XML_TEXT_NODE:
$output = trim($node->textContent);
break;
case XML_ELEMENT_NODE:
for ($i=0, $m=$node->childNodes->length; $i<$m; $i++) {
$child = $node->childNodes->item($i);
$v = domnode_to_array($child);
if(isset($child->tagName)) {
$t = $child->tagName;
if(!isset($output[$t])) {
$output[$t] = array();
}
$output[$t][] = $v;
}
elseif($v || $v === '0') {
$output = (string) $v;
}
}
if($node->attributes->length && !is_array($output)) { //Has attributes but isn't an array
$output = array('@content'=>$output); //Change output into an array.
}
if(is_array($output)) {
if($node->attributes->length) {
$a = array();
foreach($node->attributes as $attrName => $attrNode) {
$a[$attrName] = (string) $attrNode->value;
}
$output['@attributes'] = $a;
}
foreach ($output as $t => $v) {
if(is_array($v) && count($v)==1 && $t!='@attributes') {
$output[$t] = $v[0];
}
}
}
break;
}
return $output;
}
其他回答
参见https://github.com/gaarf/XML-string-to-PHP-array/blob/master/xmlstr_to_array.php
<?php
/**
* convert xml string to php array - useful to get a serializable value
*
* @param string $xmlstr
* @return array
*
* @author Adrien aka Gaarf & contributors
* @see http://gaarf.info/2009/08/13/xml-string-to-php-array/
*/
function xmlstr_to_array($xmlstr) {
$doc = new DOMDocument();
$doc->loadXML($xmlstr);
$root = $doc->documentElement;
$output = domnode_to_array($root);
$output['@root'] = $root->tagName;
return $output;
}
function domnode_to_array($node) {
$output = array();
switch ($node->nodeType) {
case XML_CDATA_SECTION_NODE:
case XML_TEXT_NODE:
$output = trim($node->textContent);
break;
case XML_ELEMENT_NODE:
for ($i=0, $m=$node->childNodes->length; $i<$m; $i++) {
$child = $node->childNodes->item($i);
$v = domnode_to_array($child);
if(isset($child->tagName)) {
$t = $child->tagName;
if(!isset($output[$t])) {
$output[$t] = array();
}
$output[$t][] = $v;
}
elseif($v || $v === '0') {
$output = (string) $v;
}
}
if($node->attributes->length && !is_array($output)) { //Has attributes but isn't an array
$output = array('@content'=>$output); //Change output into an array.
}
if(is_array($output)) {
if($node->attributes->length) {
$a = array();
foreach($node->attributes as $attrName => $attrNode) {
$a[$attrName] = (string) $attrNode->value;
}
$output['@attributes'] = $a;
}
foreach ($output as $t => $v) {
if(is_array($v) && count($v)==1 && $t!='@attributes') {
$output[$t] = $v[0];
}
}
}
break;
}
return $output;
}
我喜欢这个问题,一些答案对我很有帮助,但我需要将xml转换为一个支配数组,所以我将发布我的解决方案,也许以后有人需要它:
<?php
$xml = json_decode(json_encode((array)simplexml_load_string($xml)),1);
$finalItem = getChild($xml);
var_dump($finalItem);
function getChild($xml, $finalItem = []){
foreach($xml as $key=>$value){
if(!is_array($value)){
$finalItem[$key] = $value;
}else{
$finalItem = getChild($value, $finalItem);
}
}
return $finalItem;
}
?>
当遇到只有文本节点的子元素时,在接受的答案拖放属性中使用的方法。例如:
$xml = '<container><element attribute="123">abcd</element></container>';
print_r(json_decode(json_encode(simplexml_load_string($xml, "SimpleXMLElement", LIBXML_NOCDATA)),1));
Array
(
[element] => abcd
)
我的解决方案(我希望我能在这里给予赞扬,因为我确信这是从某些东西改编而来的):
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;
}
$xml = '
<aaaa Version="1.0">
<bbb>
<cccc>
<dddd id="123" />
<eeee name="john" age="24" />
<ffff type="employee">Supervisor</ffff>
</cccc>
</bbb>
</aaaa>
';
print_r(XMLtoArray($xml));
Array
(
[aaaa] => Array
(
[@attributes] => Array
(
[Version] => 1.0
)
[bbb] => Array
(
[cccc] => Array
(
[dddd] => Array
(
[@attributes] => Array
(
[id] => 123
)
)
[eeee] => Array
(
[@attributes] => Array
(
[name] => john
[age] => 24
)
)
[ffff] => Array
(
[@attributes] => Array
(
[type] => employee
)
[_value] => Supervisor
)
)
)
)
)
将一个XML字符串($buffer)转换为一个忽略属性的简化数组,并将具有相同名称的子元素分组:
function XML2Array(SimpleXMLElement $parent)
{
$array = array();
foreach ($parent as $name => $element) {
($node = & $array[$name])
&& (1 === count($node) ? $node = array($node) : 1)
&& $node = & $node[];
$node = $element->count() ? XML2Array($element) : trim($element);
}
return $array;
}
$xml = simplexml_load_string($buffer);
$array = XML2Array($xml);
$array = array($xml->getName() => $array);
结果:
Array
(
[aaaa] => Array
(
[bbb] => Array
(
[cccc] => Array
(
[dddd] =>
[eeee] =>
)
)
)
)
如果您还想拥有这些属性,可以通过SimpleXMLElement的JSON编码/解码使用它们。这通常是最简单快捷的解决方法:
$xml = simplexml_load_string($buffer);
$array = json_decode(json_encode((array) $xml), true);
$array = array($xml->getName() => $array);
结果:
Array
(
[aaaa] => Array
(
[@attributes] => Array
(
[Version] => 1.0
)
[bbb] => Array
(
[cccc] => Array
(
[dddd] => Array
(
[@attributes] => Array
(
[Id] => id:pass
)
)
[eeee] => Array
(
[@attributes] => Array
(
[name] => hearaman
[age] => 24
)
)
)
)
)
)
请注意,所有这些方法都只能在XML文档的名称空间中工作。
简单!
$xml = simplexml_load_string($xmlstring, "SimpleXMLElement", LIBXML_NOCDATA);
$json = json_encode($xml);
$array = json_decode($json,TRUE);