【问题标题】:Get Array From XML Nodes [duplicate]从 XML 节点获取数组 [重复]
【发布时间】:2014-10-07 10:55:18
【问题描述】:

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

但不起作用。

【问题讨论】:

  • SimpleXMLElement 实例需要转换为字符串
  • 您非常接近但只是犯了一个小错误(顺便说一句,一个常见的错误)认为您需要指定根元素Names,但您不需要:eval.in/204444 - 但不起作用也不是一个好的编程问题。

标签: php xml


【解决方案1】:

获得您想要的数组的最快方法是这样做:

$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"
}

demo here

正如 OIS 在他的回答中建议的那样,您也可以使用 SimpleXMLElement::xpath(),它可以让您摆脱那些丑陋的嵌套循环。除了他建议的 XPath,我可能会采用这种方法:

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

【讨论】:

    【解决方案2】:

    我只是使用 xpath,因为我觉得这更容易。使用 [@lang] 只会选择具有属性 lang 的名称节点。编辑:因为这只是一个摘录,所以我做了 //Names 所以如果它不是 root 也可以找到它。

    $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"
    }
    

    【讨论】:

    • 使用 xPath 是个好主意,但 $xml-&gt;xpath('//Name[@lang]') 在这里不是更有意义吗?无论如何 +1 为 xpath,希望你不介意我将它添加到我的答案中
    • @Elias Van Ootegem 只要它始终只是 /Names/Name 而没有其他节点,它们是相同的。如果还有其他节点并且它们包含名称,那么 //Name 可能包含太多命中。
    • 这正是我使用//Name[@lang] 的原因:来自OP 给我们的相当短的XML sn-p 的aprat,我们真的不知道实际数据是什么样的。广泛的 xpath 可能包含太多节点,但我宁愿拥有太多数据而不是太少。嗯,由 OP 决定
    • 那我宁愿使用 //Names/Name tbh
    猜你喜欢
    • 2013-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-28
    相关资源
    最近更新 更多