【问题标题】:XML to Array? [PHP]XML 到数组? [PHP]
【发布时间】:2012-08-22 08:03:04
【问题描述】:

嗯,我在将 xml 更改回数组时遇到了问题....如果每个 xml 都遵循相同的格式,但每个 XML 都不同,<Formula> 标记、公式名称和 movespeed 除外 例如:

<Formula>
<formulaname>Basic</formulaname>
<movespeed>1</movespeed>
<str>4</str>
<dex>3</dex>
<int>1</int>
<will>2</will>
</Formula>

<Formula>
<formulaname>Basic</formulaname>
<movespeed>1</movespeed>
<box>4</box>
<chicken>3</chicken>
<ducks>1</ducks>
<cereal>2</cereal>
</Formula>

我尝试过的:

$xml = simplexml_load_file("test.xml");
print_r($xml);

这实际上是prints 的东西,但我无法超越它甚至echo 它..

foreach($xml->text as $string) { 
  print_r($string);
  echo 'attributes: '. $string->attributes() .'<br />';
}

没用,原来是给strings的,但都不是strings...

foreach ($xml->Formula as $element) {
  foreach($element as $key => $val) {
   echo "{$key}: {$val}";
  }

也没有工作,我需要这样的东西才能工作,这样我就可以使用来自array 的值,而无需知道该值究竟会被调用什么......

【问题讨论】:

  • 你的 XML 有根标签吗?还是只是一堆公式标签?
  • 您是否能够使用 XML?如果您能够改用 JSON,则只需一个简单的 json_decode($json, TRUE) 调用即可。
  • attributes 是一个对象,将其类型转换为一个数组 $attributes = $string->attributes(); $attributes = (array) $attributes;那么你就可以随心所欲地抓住任何东西。
  • xml 显示得非常好,也是的,我很遗憾地被锁定在使用 XML 中。 $attributes = $string->attributes(); $attributes = (数组);回声'属性:'。 $attributes .'
    ';出错了
  • 建议在这里阅读:php.net/manual/en/class.simplexmliterator.php -- cmets 中有几个 XMl2Array 示例函数。

标签: php xml arrays


【解决方案1】:

这是你最好的选择,它应该消除所有 SimpleXMLElement 对象,而只给你数组:

$xml = simplexml_load_file("test.xml");
$xml_array = unserialize(serialize(json_decode(json_encode((array) $xml), 1)));
print_r($xml_array);

区别在于:



还有这个:



希望对您有所帮助... :)

【讨论】:

  • 适用于我的简短变体:$xml_array = json_decode(json_encode((array) $firmInfoXml), 1)
  • 甚至更短:json_decode(json_encode($xml), 1);(无需转换)
【解决方案2】:

你不能通过在节点本身上使用foreach来访问子节点,你需要使用.children()

$s =<<<EOS
<root>
<Formula>
<formulaname>Basic</formulaname>
<movespeed>1</movespeed>
<box>4</box>
<chicken>3</chicken>
<ducks>1</ducks>
<cereal>2</cereal>
</Formula>
</root>
EOS;

$xml = simplexml_load_string($s);

foreach ($xml->Formula as $element) {
    foreach($element->children() as $key => $val) {
        echo "{$key}: {$val}";
    }
}

【讨论】:

  • v.v 没有回显任何内容
  • @GinzoMilani 更新了对我有用的答案
  • teamrequeue.net/DMQuests/upload/users/monckey100/formulas/… 这是我用作测试的 xml,但每个 xml 的内容都不同
  • @GinzoMilani - 你能更详细地解释一下为什么这对你不起作用吗?据我所知,如果您将 XML 放在上面的代码中,它应该会打印出子元素。 +1
  • @GinzoMilani 你的 XML 应该有一个根节点;如果你没有,你可以跳过外循环:)
【解决方案3】:

对于您的示例,此代码就足够了:

$xml = simplexml_load_file('formula.xml');
$arr = (array) $xml;
var_dump($arr);

你的 xml 进入数组
formula.xml 包含您的 xml

【讨论】:

  • 仅适用于 1 级(对于更深的树,@jerdiggity 的答案更好)
【解决方案4】:

如果同一个节点有cdata和和属性,使用上面的方法会省略属性。

试试这个方法:

function xml2array($xmlObject, $out = [])
{
    foreach($xmlObject->attributes() as $attr => $val)
        $out['@attributes'][$attr] = (string)$val;

    $has_childs = false;
    foreach($xmlObject as $index => $node)
    {
        $has_childs = true;
        $out[$index][] = xml2array($node);
    }
    if (!$has_childs && $val = (string)$xmlObject)
        $out['@value'] = $val;

    foreach ($out as $key => $vals)
    {
        if (is_array($vals) && count($vals) === 1 && array_key_exists(0, $vals))
            $out[$key] = $vals[0];
    }
    return $out;
}
$xml = simplexml_load_string($xml_string, 'SimpleXMLElement', LIBXML_NOCDATA);
$arr = xml2array($xml);

【讨论】:

  • 在每个节点上添加一个无用的 @value 键,即使在不需要时(例如:当没有属性时),但 +1 用于指出当节点包含值时属性在上述方式上丢失.
  • +1 它不是没用的,因为你知道它是一个值而不是一个属性。如果您需要解析结果数组,则无需在解释值之前检查节点是否具有属性。这应该是公认的答案,因为问题是如何将 xml 转换为 php 中的数组(不丢失数据)
猜你喜欢
  • 2011-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-04
  • 2012-03-21
相关资源
最近更新 更多