【问题标题】:parse xmlsimple to array将 xmlsimple 解析为数组
【发布时间】:2019-03-31 22:24:29
【问题描述】:

我有以下:

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,但没有成功。有什么建议吗?我看不到错误。 提前致谢!

【问题讨论】:

  • 那么你想要的输出到底是什么?你想维护元素的层次结构还是想要一个扁平化或半扁平化的数组?我想发布一个答案,但你的问题有点不清楚。
  • 正在得到daughter1,你只是在覆盖它。

标签: php arrays xml


【解决方案1】:

问题是您存储的是属性元素而不是实际值,您需要做的就是通过添加(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) 的原因,它只是删除任何空值。

编辑 2:

如果你想要一个非递归的解决方案,使用 DOMDocument 有一种简单的方法可以使用 $doc-&gt;getElementsByTagName("child"); 获取所有 &lt;child&gt; 元素,最好检查它是否具有 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);

【讨论】:

  • 我需要取daughter1的值
  • 如果这解决了您的问题,请考虑将其标记为已回答 - meta.stackexchange.com/questions/5234/…。这也适用于您提出的其他问题。
  • @Konstantinos 比标记接受的答案更重要的是写一个清晰的问题。请澄清您确切想要的输出。根据您的措辞,有些人可能认为您想要daughter1。我对你的数据结构的深度更感兴趣。
  • @mickmackusa,关于接受答案的重点更多是关于接受答案的一般想法,他们有几个问题,他们似乎有答案并留下了 cmets,但他们没有接受其中任何一个(此时)。也(只是一件小事),但澄清问题的要求会更好地放在问题本身上吗?
【解决方案2】:

如果您只是在寻找一个包含所有 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-16
    • 2011-11-28
    • 1970-01-01
    • 1970-01-01
    • 2016-06-06
    • 1970-01-01
    • 2011-07-02
    相关资源
    最近更新 更多