如何使用 simpleXML 将 ul li a tree 解析为嵌套数组?

How do I parse ul li a tree into a nested array using simpleXML?

我正在编写一个 PHP 脚本,该脚本请求 xml 数据回复:来自第三方 API(订单管理系统)的客户订单,并且由于主要 API 调用无法正常工作(他们也无意修复它),我可以获得所需数据的唯一方法是使用 returns 作为 jstree 的调用(html: ul li a) 格式如下:

<ul>
   <li>
      <a>Order</a>
      <ul>
         <li>
            <a>Id</a>
            <ul>
               <li>13390</li>
            </ul>
         </li>
         <li>
            <a>OrderNumber</a>
            <ul>
               <li>13390</li>
            </ul>
         </li>
<li>
            <a>LineItems</a>
            <ul>
               <li>
                  <a>LineItem</a>
                  <ul>
                     <li>
                        <a>Id</a>
                        <ul>
                           <li>21598</li>
                        </ul>
                     </li>
                     <li>
                        <a>Subtotal</a>
                        <ul>
                           <li>45.79</li>
                        </ul>
                     </li>
                     <li>
                        <a>SubtotalTax</a>
                        <ul>
                           <li>9.16</li>
                        </ul>
                     </li>
                     <li>
                        <a>Total</a>
                        <ul>
                           <li>45.79</li>
                        </ul>
                     </li>
                     <li>
                        <a>TotalTax</a>
                        <ul>
                           <li>9.16</li>
                        </ul>
                     </li>
                     <li>
                        <a>Price</a>
                        <ul>
                           <li>45.79</li>
                        </ul>
                     </li>
                     <li>
                        <a>Quantity</a>
                        <ul>
                           <li>1</li>
                        </ul>
                     </li>
                     <li><a>TaxClass</a></li>
                     <li>
                        <a>Name</a>
                        <ul>
                           <li>Product Name</li>
                        </ul>
                     </li>
                     <li>
                        <a>ProductId</a>
                        <ul>
                           <li>4208</li>
                        </ul>
                     </li>
                     <li>
                        <a>Sku</a>
                        <ul>
                           <li>ABCD-S</li>
                        </ul>
                     </li>
                     <li><a>Meta</a></li>
                  </ul>
               </li>
            </ul>
         </li>
      </ul>
   </li>
</ul>

我需要将上述所有字符串解析为一个嵌套数组,这样我就可以遍历订单项并利用其中的值执行某些操作。为了尽可能简单,我从上面省略了大量的数据树。

我已经尝试过 SimpleHTMLDom,但随着我进一步开发脚本并扩展操作量,它导致了各种内存和服务器错误,因此选择了 SimpleXML,但仍然对其他选项持开放态度以完成工作。

到目前为止,我得到了以下递归 PHP 函数:

function ul_to_array ($ul) {
  if (is_string($ul)) {
    // encode ampersand appropiately to avoid parsing warnings
    $ul=preg_replace('/&(?!#?[a-z0-9]+;)/', '&amp;', $ul);
    if (!$ul = simplexml_load_string($ul)) {
      trigger_error("Syntax error in UL/LI structure");
      return FALSE;
    }
    return ul_to_array($ul);
  } else if (is_object($ul)) {
    $output = array();
    foreach ($ul->li as $li) {
        $output[] = (isset($li->ul)) ? ul_to_array($li->ul) : (string) $li;
    }
    return $output;
  } else return FALSE;
}

但它输出的数组是这样的:

Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [0] => 13390
                )

            [1] => Array
                (
                    [0] => 13390
                )
            [2] => Array
                (
                    [0] => Array
                        (
                            [0] => Array
                                (
                                    [0] => 21598
                                )

                            [1] => Array
                                (
                                    [0] => 45.79
                                )

                            [2] => Array
                                (
                                    [0] => 9.16
                                )

                            [3] => Array
                                (
                                    [0] => 45.79
                                )

                            [4] => Array
                                (
                                    [0] => 9.16
                                )

                            [5] => Array
                                (
                                    [0] => 45.79
                                )

                            [6] => Array
                                (
                                    [0] => 1
                                )

                            [7] => 
                            [8] => Array
                                (
                                    [0] => Product Name
                                )

                            [9] => Array
                                (
                                    [0] => 4208
                                )

                            [10] => Array
                                (
                                    [0] => ABCD-S
                                )

                            [11] => 
                        )

                )

我想要的结果是数组看起来像这样:

Array
(
    ["Order"] => Array
        (
            ["Id"] => 13390

            ["OrderNumber"] => 13390

            ["LineItems"] => Array
                (
                    [0] => Array
                        (
                            ["Id"] => 21598

                            ["Subtotal"] => 45.79

                            ["SubtotalTax"] =>  9.16

                            ["Total"] => 45.79

                            ["TotalTax"] => 9.16

                            ["Price"] => 45.79

                            ["Quantity"] => 1

                            ["TaxClass"] => 
                            ["Name"] => Product Name

                            ["ProductId"] => 4208

                            ["Sku"] => ABCD-S

                            ["Meta"] => 
                        )

                )

        )
)

当 $li->a 不为空时,我尝试用 $output[$li->a] = 替换 $output[] = ,但我最终得到了错误和一个空数组。

如有任何帮助,我们将不胜感激,

谢谢,

此处的主要变化仅在于处理 XML...

的循环
    foreach ($ul->li as $li) {
        $newLayer = (isset($li->ul)) ? ul_to_array($li->ul) : trim((string) $li);
        $output[ (string)$li->a ] = $newLayer[''] ?? $newLayer;
    }

(string)$li->a部分使用锚标签的值作为数组的索引。

$newLayer[''] ?? $newLayer 处理存储实际值的实例,因此值在元素 '' 中,如果未设置此元素,则它将是子菜单。

根据您的示例,这给出了...

Array
(
    [Order] => Array
        (
            [Id] => 13390
            [OrderNumber] => 13390
            [LineItems] => Array
                (
                    [LineItem] => Array
                        (
                            [Id] => 21598
                            [Subtotal] => 45.79
                            [SubtotalTax] => 9.16
                            [Total] => 45.79
                            [TotalTax] => 9.16
                            [Price] => 45.79
                            [Quantity] => 1
                            [TaxClass] => 
                            [Name] => Product Name
                            [ProductId] => 4208
                            [Sku] => ABCD-S
                            [Meta] => 
                        )

                )

        )

)