我有这个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"
}