如何使用 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]+;)/', '&', $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] =>
)
)
)
)
我正在编写一个 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]+;)/', '&', $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] =>
)
)
)
)