php - 用于正确解析包含数组中每个项目的一个子元素的 XML 元素的 PHP 函数
问题描述
我正在搜索可以解析 XML 字符串的现有或自定义函数,如下所示:
<root>
<products>
<product>
<sku>001</sku>
<name>Product 1</name>
</product>
<product>
<sku>002</sku>
<name>Product 2</name>
</product>
</products>
</root>
成这样的数组:
Array
(
[products] => Array
(
[0] => Array
(
[sku] => 001
[name] => Product 1
)
[1] => Array
(
[sku] => 002
[name] => Product 2
)
)
)
我一直在使用以下内容从 XML 中获取一个不错的数组:
$arr = json_decode(json_encode(new SimpleXMLElement($xml)), true);
但是正如您所看到的,该数组带有额外的“产品”键,有点时髦:
Array
(
[products] => Array
(
[product] => Array
(
[0] => Array
(
[sku] => 001
[name] => Product 1
)
[1] => Array
(
[sku] => 002
[name] => Product 2
)
)
)
)
此函数应该能够解析任何大小的 xml 并以相同的方式正确格式化数组,而无需知道任何元素名称。就我而言,我不需要担心收集任何属性或类似的东西。
我一直在玩弄创建一个在解析数组时使用 Xpath 的函数的想法,但还没有成功地创建/找到一个可以按需要工作的函数。
解决方案
这是我不久前在将 XML 内容转换为数组时开始使用的函数。
完整的描述可以在这里找到: https ://totaldev.com/flatten-multidimensional-arrays-php/
对于您的示例,您应该能够像这样使用它:
// Flatten an array of data with full-path string keys
function flat($array, $separator = '|', $prefix = '', $flattenNumericKeys = false, $appendNumericArrayKeys = true) {
$result = [];
foreach($array as $key => $value) {
$separatorKey = (empty($prefix) ? '' : $separator) . $key;
$valueIsNumericArray = is_array($value) && count(array_filter(array_keys($value), 'is_string')) < 1;
if($appendNumericArrayKeys === false && $valueIsNumericArray) $separatorKey = '';
$new_key = $prefix . $separatorKey;
// Make sure value isn't empty
if(is_array($value)) {
if(empty($value)) $value = null;
else if(count($value) == 1 && isset($value[0]) && is_string($value[0]) && empty(trim($value[0]))) $value = null;
}
$hasStringKeys = is_array($value) && count(array_filter(array_keys($value), 'is_string')) > 0;
if(is_array($value) && ($hasStringKeys || $flattenNumericKeys)) $result = array_merge($result, flat($value, $separator, $new_key, $flattenNumericKeys, $appendNumericArrayKeys));
else $result[$new_key] = $value;
}
return $result;
}
它基本上将您从 XML 中获得的数组扁平化为一个数组,其中的键是元素的字符串路径。你会像这样使用它:
$arr = json_decode(json_encode(new SimpleXMLElement($xml)), true);
$flattenedArray = flat($arr, '|', '', false, false);
echo '<pre>'.print_r($flattenedArray, true).'</pre>';
展平数组的输出如下所示:
Array
(
[products] => Array
(
[0] => Array
(
[sku] => 001
[name] => Product 1
)
[1] => Array
(
[sku] => 002
[name] => Product 2
)
)
)
推荐阅读
- django - 如何在 Django 中为抽象基类获取唯一的序列号?
- angular - Interrupt sequential concatMap calls after error happens in one of them
- reactjs - reactjs在重新渲染父组件时弹出打开和关闭
- gulp - 如何修复 gulpfile.js 以避免“您是否忘记发出异步完成信号?” 当运行“gulp ngrok-serve”并且没有定义任务时?
- javascript - Select2 奇怪的下拉定位
- java - 当我遵循的每个示例都使用相同的转换时,为什么我无法将字符串转换为没有致命异常的浮点数?
- python - scrapy 到 csv 更改数据格式
- ios - UICollectionView:根据UIButton的文字宽度为每个单元格应用动态宽度
- windows - 是否可以使用 Windows 计划任务自动登录?
- mongodb - 如何查询数组并从 MongoDB 中检索它