将xmlsimple解析为数组

时间:2018-10-27 10:22:27

标签: php arrays xml

我有以下内容:

function Recurse1($xml, $array, $i){
    $a = array();
    foreach($xml - > children() as $key => $child) {
        $array[$key][$i] = $child - > attributes() - > role;
        $i++;
        $a = array_merge($array, Recurse1($child, $array, $i));
    }
    return $a;
}

var_dump(Recurse1($xml, array(), 0));
$xml = new SimpleXMLElement(
'<person>
    <child role="son1">
        <child role="daughter1"/>
    </child>
    <child role="daughter2">
        <child role="son2">
            <child role="son3"/>
        </child>
    </child>
</person>'
);

我得到以下信息:

array(1) { 
  ["child"]=> array(4) { 
    [0]=> object(SimpleXMLElement)#59 (1) { 
      [0]=> string(4) "son1" 
    } 
    [1]=> object(SimpleXMLElement)#71 (1) { 
      [0]=> string(9) "daughter2" 
    } 
    [2]=> object(SimpleXMLElement)#77 (1) { 
      [0]=> string(4) "son2" 
    } 
    [3]=> object(SimpleXMLElement)#83 (1) { 
      [0]=> string(4) "son3" 
    } 
  } 
}

我正试图让女儿1,但没有任何希望。有任何建议吗?我看不到错误。 预先感谢!

2 个答案:

答案 0 :(得分:2)

问题是您存储的是attribute元素,而不是实际值,您所要做的只是通过添加(string) ...

将其强制转换为字符串。
$array[$key][$i] = (string)$child->attributes()->role;

哪个给...

array(1) {
  'child' =>
  array(4) {
    [0] =>
    string(4) "son1"
    [1] =>
    string(9) "daughter2"
    [2] =>
    string(4) "son2"
    [3] =>
    string(4) "son3"
  }
}

编辑:

为了获得所有子节点,我对大部分代码进行了重新设计以简化其工作方式。

function Recurse1($xml)
{
    $array = [(string)$xml['role']];
    foreach ($xml->children() as $child)
    {
        $array = array_merge($array, Recurse1($child));
    }

    return array_filter($array);
}

$xml = new SimpleXMLElement(
    '<person>
<child role="son1">
<child role="daughter1"/>
</child>
<child role="daughter2">
<child role="son2">
<child role="son3"/>
</child>
</child>
</person>');
var_dump(Recurse1($xml));

如您所见,Recurse1()现在仅获取XML并首先输出value属性,然后对所有子节点重复此操作。有时节点没有value属性,这就是为什么它返回array_filter($array)的原因,<child>只会删除所有空值。

编辑2:

如果您要使用非递归解决方案,则使用DOMDocument可以使用$doc->getElementsByTagName("child");来获取所有role元素的简便方法,最好检查它是否具有$doc = new DOMDocument(); $doc->loadXML($xml); $childE = $doc->getElementsByTagName("child"); $list = []; foreach ( $childE as $child ) { if ( $child->hasAttribute("role") ) { $list[] = $child->getAttribute("role"); } } print_r($list); 属性,但是如果有的话,只需将其添加到列表中即可。

([^|\s]+)\s*\|\s*([^^\s]+)(?:\s*\^\s*|$)

答案 1 :(得分:1)

如果您只想查找包含所有role值的一维数组,则可以省去递归卷积,只需让DomDocument&Xpath用一个简单,简单的方法为您完成所有工作即可,可读查询(对您来说更轻松,并且对于希望查看您的代码的下一个开发人员来说很容易):

代码:(Demo

$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
foreach ($xpath->evaluate('//child/@role') as $attr) {
    $result[] = $attr->value;
}
var_export($result);

输出:

array (
  0 => 'son1',
  1 => 'daughter1',
  2 => 'daughter2',
  3 => 'son2',
  4 => 'son3',
)

或者,如果要维护输出数组中的层次结构,则可以像这样使用this existing StackOverflow solutionDemo