xml转array

分享一个将xml文件转成数组的方法。

    /**
     * @purpose: 将xml转化为数组
     * @param mixed $url xml文件或者xml所在的url
     * @param int $getAttributes 是否获取属性值,若为true,如果xml中有attributes,将attributes存入attr里面
     * @param string $priority 如果设置了$priority=tag,则标签的值作为数组中该标签作为key的value,否则会增加一级value的key
     * @return array|void
     */
    public static function xml2array($url, $getAttributes = true, $priority = 'tag')
    {
        $contents = ''; //临时保存xml内容
        $arrXml = [];   //xml转数组后数据存放位置
        if (!function_exists('xml_parser_create')) {
            goto __end;
        }
        $parser = xml_parser_create('');
        if (!($fp = @ fopen($url, 'rb'))) {
            goto __end;
        }
        while (!feof($fp)) {
            $contents .= fread($fp, 8192);
        }
        fclose($fp);

        xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8");
        xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
        xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
        xml_parse_into_struct($parser, trim($contents), $xmlValues);
        xml_parser_free($parser);

        if ($xmlValues) {
            $current = &$arrXml;
            $repeatedTagIndex = array();
            foreach ($xmlValues as $data) {
                //确保每次循环的时候,没有$attributes和$value这两个变量
                unset ($attributes, $value);
                //节点类型,open,close,complete
                $type = ArrayHelper::getValue($data, 'type');
                //属于几级标签,对应数组的几维
                $level = ArrayHelper::getValue($data, 'level');
                //xml标签名,作为数组的key
                $tag = ArrayHelper::getValue($data, 'tag');
                //每个标签里面的数据
                $value = ArrayHelper::getValue($data, 'value');
                $result = array();
                $attributesData = array();

                if (isset ($value)) {
                    if ($priority == 'tag'){
                        $result = $value;
                    }else{
                        $result['value'] = $value;
                    }
                }
                if (isset ($attributes) && $getAttributes) {
                    foreach ($attributes as $attr => $val) {
                        if ($priority == 'tag'){
                            $attributesData[$attr] = $val;
                        }else{
                            //将所有的属性以数组的形式保存在$result['attr']下面
                            $result['attr'][$attr] = $val;
                        }
                    }
                }

                //根据不同的节点类型所属维度将数据变成一个数组
                if ($type == "open") {
                    $parent[$level - 1] = &$current;
                    if (!is_array($current) or (!in_array($tag, array_keys($current)))) {
                        $current[$tag] = $result;
                        if ($attributesData){
                            $current[$tag . '_attr'] = $attributesData;
                        }
                        $repeatedTagIndex[$tag . '_' . $level] = 1;
                        $current = &$current[$tag];
                    } else {
                        if (isset ($current[$tag][0])) {
                            $current[$tag][$repeatedTagIndex[$tag . '_' . $level]] = $result;
                            $repeatedTagIndex[$tag . '_' . $level]++;
                        } else {
                            $current[$tag] = [
                                $current[$tag],
                                $result,
                            ];
                            $repeatedTagIndex[$tag . '_' . $level] = 2;
                            if (isset ($current[$tag . '_attr'])) {
                                $current[$tag]['0_attr'] = $current[$tag . '_attr'];
                                unset ($current[$tag . '_attr']);
                            }
                        }
                        $lastItemIndex = $repeatedTagIndex[$tag . '_' . $level] - 1;
                        $current = &$current[$tag][$lastItemIndex];
                    }
                } elseif ($type == "complete") {
                    if (!isset ($current[$tag])) {
                        $current[$tag] = $result;
                        $repeatedTagIndex[$tag . '_' . $level] = 1;
                        if ($priority == 'tag' && $attributesData)
                            $current[$tag . '_attr'] = $attributesData;
                    } else {
                        if (isset ($current[$tag][0]) && is_array($current[$tag])) {
                            $current[$tag][$repeatedTagIndex[$tag . '_' . $level]] = $result;
                            if ($priority == 'tag' && $getAttributes && $attributesData) {
                                $current[$tag][$repeatedTagIndex[$tag . '_' . $level] . '_attr'] = $attributesData;
                            }
                            $repeatedTagIndex[$tag . '_' . $level]++;
                        } else {
                            $current[$tag] = [
                                $current[$tag],
                                $result,
                            ];
                            $repeatedTagIndex[$tag . '_' . $level] = 1;
                            if ($priority == 'tag' && $getAttributes) {
                                if (isset ($current[$tag . '_attr'])) {
                                    $current[$tag]['0_attr'] = $current[$tag . '_attr'];
                                    unset ($current[$tag . '_attr']);
                                }
                                if ($attributesData) {
                                    $current[$tag][$repeatedTagIndex[$tag . '_' . $level] . '_attr'] = $attributesData;
                                }
                            }
                            $repeatedTagIndex[$tag . '_' . $level]++; //0 and 1 index is already taken
                        }
                    }
                } elseif ($type == 'close') {
                    $current = &$parent[$level - 1];
                }
            }
        }
        __end:

        return $arrXml;
    }

上面的 这几行,如果不是使用的yii框架,可用 extract($data)代替。

//节点类型,open,close,complete
$type = ArrayHelper::getValue($data, 'type');
//属于几级标签,对应数组的几维
$level = ArrayHelper::getValue($data, 'level');
//xml标签名,作为数组的key
$tag = ArrayHelper::getValue($data, 'tag');
//每个标签里面的数据
$value = ArrayHelper::getValue($data, 'value');

 

posted @ 2019-04-29 14:07  Chrdai  阅读(641)  评论(0编辑  收藏  举报