php之XML转数组函数的详解


Posted in PHP onJune 07, 2013

如下所示:

<?
/** 
* xml2array() will convert the given XML text to an array in the XML structure. 
* Link: http://www.bin-co.com/php/scripts/xml2array/ 
* Arguments : $contents - The XML text 
*                 $get_attributes - 1 or 0. If this is 1 the function will get the attributes as well as the tag values - this results in a different array structure in the return value. 
*                 $priority - Can be 'tag' or 'attribute'. This will change the way the resulting array sturcture. For 'tag', the tags are given more importance. 
* Return: The parsed XML in an array form. Use print_r() to see the resulting array structure. 
* Examples: $array =   xml2array(file_get_contents('feed.xml')); 
*               $array =   xml2array(file_get_contents('feed.xml', 1, 'attribute')); 
*/ 
function xml2array($contents, $get_attributes=1, $priority = 'tag') { 
     if(!$contents) return array(); 
     if(!function_exists('xml_parser_create')) { 
        //print "'xml_parser_create()' function not found!"; 
        return array(); 
     } 
    //Get the XML parser of PHP - PHP must have this module for the parser to work 
    $parser = xml_parser_create(''); 
    xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8"); # http://minutillo.com/steve/weblog/2004/6/17/php-xml-and-character-encodings-a-tale-of-sadness-rage-and-data-loss 
    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), $xml_values); 
    xml_parser_free($parser); 
     if(!$xml_values) return;//Hmm... 
     //Initializations 
    $xml_array = array(); 
    $parents = array(); 
    $opened_tags = array(); 
    $arr = array(); 
    $current = &$xml_array; //Refference 
     //Go through the tags. 
    $repeated_tag_index = array();//Multiple tags with same name will be turned into an array 
    foreach($xml_values as $data) { 
         unset($attributes,$value);//Remove existing values, or there will be trouble 
         //This command will extract these variables into the foreach scope 
         // tag(string), type(string), level(int), attributes(array). 
        extract($data);//We could use the array by itself, but this cooler. 
        $result = array(); 
        $attributes_data = array();          if(isset($value)) { 
             if($priority == 'tag') $result = $value; 
             else $result['value'] = $value; //Put the value in a assoc array if we are in the 'Attribute' mode 
        } 
        //Set the attributes too. 
        if(isset($attributes) and $get_attributes) { 
             foreach($attributes as $attr => $val) { 
                 if($priority == 'tag') $attributes_data[$attr] = $val; 
                 else $result['attr'][$attr] = $val; //Set all the attributes in a array called 'attr' 
            } 
         } 
        //See tag status and do the needed. 
        if($type == "open") {//The starting of the tag '<tag>' 
            $parent[$level-1] = &$current; 
             if(!is_array($current) or (!in_array($tag, array_keys($current)))) { //Insert New tag 
                $current[$tag] = $result; 
                 if($attributes_data) $current[$tag. '_attr'] = $attributes_data; 
                $repeated_tag_index[$tag.'_'.$level] = 1; 
                $current = &$current[$tag]; 
             } else { //There was another element with the same tag name 
                if(isset($current[$tag][0])) {//If there is a 0th element it is already an array 
                    $current[$tag][$repeated_tag_index[$tag.'_'.$level]] = $result; 
                    $repeated_tag_index[$tag.'_'.$level]++; 
                 } else {//This section will make the value an array if multiple tags with the same name appear together 
                    $current[$tag] = array($current[$tag],$result);//This will combine the existing item and the new item together to make an array 
                    $repeated_tag_index[$tag.'_'.$level] = 2; 
                     if(isset($current[$tag.'_attr'])) { //The attribute of the last(0th) tag must be moved as well 
                        $current[$tag]['0_attr'] = $current[$tag.'_attr']; 
                         unset($current[$tag.'_attr']); 
                     } 
                 } 
                $last_item_index = $repeated_tag_index[$tag.'_'.$level]-1; 
                $current = &$current[$tag][$last_item_index]; 
             } 
         } elseif($type == "complete") { //Tags that ends in 1 line '<tag />' 
             //See if the key is already taken. 
            if(!isset($current[$tag])) { //New Key 
                $current[$tag] = $result; 
                $repeated_tag_index[$tag.'_'.$level] = 1; 
                 if($priority == 'tag' and $attributes_data) $current[$tag. '_attr'] = $attributes_data; 
             } else { //If taken, put all things inside a list(array) 
                if(isset($current[$tag][0]) and is_array($current[$tag])) {//If it is already an array... 
                     // ...push the new element into that array. 
                    $current[$tag][$repeated_tag_index[$tag.'_'.$level]] = $result; 
                     if($priority == 'tag' and $get_attributes and $attributes_data) { 
                        $current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data; 
                     } 
                    $repeated_tag_index[$tag.'_'.$level]++; 
                 } else { //If it is not an array... 
                    $current[$tag] = array($current[$tag],$result); //...Make it an array using using the existing value and the new value 
                    $repeated_tag_index[$tag.'_'.$level] = 1; 
                     if($priority == 'tag' and $get_attributes) { 
                         if(isset($current[$tag.'_attr'])) { //The attribute of the last(0th) tag must be moved as well 
                            $current[$tag]['0_attr'] = $current[$tag.'_attr']; 
                             unset($current[$tag.'_attr']); 
                         } 
                         if($attributes_data) { 
                            $current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data; 
                         } 
                     } 
                    $repeated_tag_index[$tag.'_'.$level]++; //0 and 1 index is already taken 
                } 
             } 
         } elseif($type == 'close') { //End of tag '</tag>' 
            $current = &$parent[$level-1]; 
         } 
     } 
     return($xml_array); 
} 
?>

函数描述及例子:
$arr = xml2array(file_get_contents("tools.xml"),1,'attribute');

PHP 相关文章推荐
实现分十页分向前十页向后十页的处理
Oct 09 PHP
建立动态的WML站点(三)
Oct 09 PHP
php中的登陆login
Jan 18 PHP
php设计模式 Singleton(单例模式)
Jun 26 PHP
PHP生成图片验证码、点击切换实例
Jun 25 PHP
PHP中常用的输出函数总结
Sep 22 PHP
php写入数据到CSV文件的方法
Mar 14 PHP
非常经典的PHP文件上传类分享
May 15 PHP
php使用正则表达式去掉html中的注释方法
Nov 03 PHP
php之可变函数的实例详解
Sep 13 PHP
Yii框架分页技术实例分析
Aug 30 PHP
利用php绘制饼状图的实现代码
Jun 07 #PHP
PHP自定义大小验证码的方法详解
Jun 07 #PHP
如何用php生成扭曲及旋转的验证码图片
Jun 07 #PHP
利用php获取服务器时间的实现代码
Jun 07 #PHP
探讨PHP中OO之静态关键字以及类常量的详解
Jun 07 #PHP
PHP5常用函数列表(分享)
Jun 07 #PHP
深入理解php的MySQL连接类
Jun 07 #PHP
You might like
php源码分析之DZX1.5加密解密函数authcode用法
2015/06/17 PHP
ZF框架实现发送邮件的方法
2015/12/03 PHP
PHP7常量数组用法分析
2016/09/26 PHP
PHP验证终端类型是否为手机的简单实例
2017/02/07 PHP
CLASS_CONFUSION JS混淆 全源码
2007/12/12 Javascript
javascript 自动填写表单的实现方法
2010/04/09 Javascript
事件绑定之小测试  onclick &amp;&amp; addEventListener
2011/07/31 Javascript
封装的jquery翻页滚动(示例代码)
2013/11/18 Javascript
JavaScript实现两个Table固定表头根据页面大小自行调整
2014/01/03 Javascript
node.js中的events.emitter.removeAllListeners方法使用说明
2014/12/10 Javascript
JS+CSS实现带关闭按钮DIV弹出窗口的方法
2015/02/27 Javascript
javascript算法题:求任意一个1-9位不重复的N位数在该组合中的大小排列序号
2015/04/01 Javascript
JavaScript编写推箱子游戏
2015/07/07 Javascript
浅谈JS原型对象和原型链
2016/03/02 Javascript
Angular.js如何从PHP读取后台数据
2016/03/24 Javascript
javascript iframe跨域详解
2016/10/26 Javascript
JS库之Particles.js中文开发手册及参数详解
2017/09/13 Javascript
vue使用keep-alive实现数据缓存不刷新
2017/10/21 Javascript
jquery animate动画持续运动的实例
2017/11/29 jQuery
小程序开发踩坑:页面窗口定位(相对于浏览器定位)(推荐)
2019/04/25 Javascript
autojs 蚂蚁森林能量自动拾取即给指定好友浇水的实现方法
2020/05/03 Javascript
Vuejs通过拖动改变元素宽度实现自适应
2020/09/02 Javascript
[02:23]完美世界全国高校联赛街访DOTA2第一期
2019/11/28 DOTA
用python删除java文件头上版权信息的方法
2014/07/31 Python
django批量导入xml数据
2016/10/16 Python
Python模糊查询本地文件夹去除文件后缀的实例(7行代码)
2017/11/09 Python
浅析python协程相关概念
2018/01/20 Python
利用python画出折线图
2018/07/26 Python
python绘制BA无标度网络示例代码
2019/11/21 Python
python搜索算法原理及实例讲解
2020/11/18 Python
全球高级音频和视频专家:HiDef Lifestyle
2019/08/02 全球购物
七年级地理教学反思
2014/01/26 职场文书
高中生职业规划范文
2014/03/09 职场文书
高一学生期末评语
2014/04/25 职场文书
2014年建筑工程工作总结
2014/12/03 职场文书
幼儿体育课教学反思
2016/02/16 职场文书