PHP函数正确解析XML元素,该XML元素包含数组中每个项目的一个子元素

时间:2018-09-26 04:40:01

标签: php arrays xml-parsing

我正在搜索可以解析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的函数的想法,但尚未成功创建/查找可以按需工作的函数。

1 个答案:

答案 0 :(得分:1)

这是我将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
                )

        )

)