从XML节点获取数组


Get Array From XML Nodes

我有这个xml摘录:

<Names>
<Name lang="en">Soccer</Name>
<Name lang="it">Calcio</Name>
</Names>

我想要一个像这样的阵列

$names = array(    
   "en" => "Soccer",
   "it" => "Calcio"
)

我尝试使用simple_load_file(),然后遍历节点:

for($i=0;$i<count($xmlObject->Names->Name);$i++):
  $output[$xmlObject->Names->Name[$i]['lang'] = $xmlObject->Names->Name[$i];
endfor;

但不起作用。

获得所需数组的最快方法是:

$dom = simplexml_load_file($yourFile);
$result = array();
foreach ($dom as $node)
{//iterate over elements
    if ($node->getName() === 'Name')
    {//make sure to only process Name tags
         $lang = null;
         foreach ($node->attributes() as $name => $val)
         {//find the attribtues
             if ($name == 'lang')
             {//we have the lang attribute
                 $lang = (string) $val;//cast to string!
                 break;//we're done here
             }
         }
         if ($lang)
             $result[$lang] = (string) $node;//cast node to string to get its contents
    }
}
var_dump($result);

输出为:

array(2) {
  ["en"]=>
  string(6) "Soccer"
  ["it"]=>
  string(6) "Calcio"
}

此处演示

正如OIS在他的回答中所建议的那样,您也可以使用SimpleXMLElement::xpath(),它允许您去掉那些丑陋的嵌套循环。除了他建议的XPath之外,我可能会选择这种方法:

foreach ($dom->xpath('//Name[@lang]') as $name)
    $result[(string) $name['lang']] = (string) $name;

我只是简单地使用xpath,因为我觉得这更容易。使用[@lang]时,只会选择属性为lang的Name节点。编辑:由于这只是一个摘录,我把它//命名了,所以如果它不是根,也会被找到。

$test = <<< EOF
<Names>
<Name lang="en">Soccer</Name>
<Name lang="it">Calcio</Name>
</Names>
EOF;
$xml = simplexml_load_string($test);
$arr = array();
foreach ($xml->xpath("//Names/Name[@lang]") as $node) {
    $arr[(string) $node["lang"]] = (string) $node;
}
var_dump($arr);

输出:

array(2) {
  ["en"]=>
  string(6) "Soccer"
  ["it"]=>
  string(6) "Calcio"
}