【问题标题】:How to get PHP SimpleXML Child Nodes into an array within an array如何将 PHP SimpleXML 子节点放入数组中的数组中
【发布时间】:2015-06-10 07:32:31
【问题描述】:

问题背景

我有一个很大的 XML 文件,我正在尝试将其解析为 PHP 数组。

我的文件结构是这样的

<orders>
  <order>
    <value1></value1>
    <value2></value3>
    <value2></value3>
    <items>
      <item></item>
      <price></price>
    </items>
  </order>
</orders>

等等更多的值。 我的 PHP 函数是这样的

public function outputNodes() {
    // this function creates/returns an array of all the XML nodes and child nodes
    // we do not know how many custom attributes there may be for orders, so this
    // handles them programmatically with count

if (file_exists($this->getFilePath())) { // this checks to make sure there is a file

    $orders = array(); //create blank array for orders

    $obj = $this->getXML($this->getFilePath()); // start by getting XML object

    $order = $obj->children();
    $oCount = count($order);  //How many orders are there?

    $topNodes = $obj->order->children();
    $topNodesCount = count($topNodes); //How many nodes does each order have?

    //begin looping through orders

    for($i=0;$i<$oCount;$i++) {

        $vals = array(); //for each order create the array to store the values of items node

         foreach($topNodes as $key => $value) { //for each top level nodes do something

             if((string)$key == "items"){ //checks to see if this top level node is the items node
                $cobj = $obj->order->items->children(); //if it is create object of the children of node
                foreach($cobj as $k =>$v) { //for each child of items node do something
                    $v[(string)$k] = (string)$v; //creates a temporary array of the child names/values of items node
                    }
                $vals[] = $v; //places them into $vals array
                $ord[(string)$key] = $vals; //places entire $vals array into temp ord array for output
                }
            else {
            $ord[(string)$key] = (string)$value;
            }           
         }
         $orders[] = $ord;
    }
    return $orders;
}
 else {
     return "Error";
     }
}

现在要明确一点,这段代码理论上可以正常工作,它确实将 $vals[] 数组放入 $orders[] 数组,但是它是这样的:

[items] => Array ( [0] => SimpleXMLElement Object ( [@attributes] => Array ( [item] => ) [item_name] => Nameof Product [item_price] => $8.00 [item_quantity] => 12 ) ) )

问题

那么我有两个问题。首先我怎样才能阻止它把Array ( [0] =&gt; SimpleXMLElement Object ( [@attributes]这个错误信息放进去?

其次,更重要的是,我如何修改代码以便不必按名称调用项目节点,我宁愿让它检查 任何给定节点是否有更多孩子,它会自动将它们拉出到一个数组中?

我宁愿不必每次有更多子节点时都编写新代码,只需检查一下:是否有子节点?如果是,获取它们并将它们显示在嵌套数组中

提前致谢

【问题讨论】:

  • 我也有一个问题:使用 SimpleXMLElement 而不是数组有什么问题?它比数组更灵活。那么为什么要为转换烦恼呢?
  • 该程序的另一部分将添加一个 jQuery/AJAX 层,并且 PHP 数组在 AJAX 上的表现比 SimpleXMLElements 更好,至少这是我一直相信的。这也是一种概念证明,我只想完全理解解析 XML 的所有角度。
  • jQuery 接受 XML 以及响应。只是说。

标签: php arrays xml xml-parsing simplexml


【解决方案1】:

实现这一点的一种方法是遍历文档中的所有元素,然后根据数据流构建数组:

$builder = new StructureBuilder();

foreach ($xml->xpath('//*') as $element) {
    $depth  = count($element->xpath("./ancestor::*"));
    $builder->add($depth, $element->getName(), trim($element));
}

print_r($builder->getStructure());

使用你的示例数据是:

Array
(
    [orders] => Array
        (
            [order] => Array
                (
                    [value1] => 
                    [value2] => 
                    [value3] => 
                    [items] => Array
                        (
                            [item] => 
                            [price] => 
                        )

                )

        )

)

它是如何工作的? StructureBuilder 跟踪结构中的哪个元素已为$depth 做好准备。你可以find the full example code as gist

您还可以看到这个先前的答案PHP Parse XML response with many namespaces,它还询问了如何转换。关于缩进的例子更详细。

【讨论】:

  • 谢谢,我会在接下来的 24 小时内尝试一下,然后告诉你进展如何。我已经很晚了,我整天都在编码,哈哈
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-27
  • 2011-02-20
  • 1970-01-01
  • 2011-04-30
相关资源
最近更新 更多