通用XML文件数据解析的PHP类
发布时间:2020-12-13 14:11:15 所属栏目:PHP教程 来源:网络整理
导读:网上那种可在php4,5默认配置环境下运行的通用解析XML的PHP类,好像不多 至少我没找到,所以就写了这个,放上来大家讨论一下! 希望能得到各位宝贵的意见,并能完善此类! 我作了几个测试的路径! 大家可先看看效果! 源文件下载在下面!.... 为了大家看得方便,注释有点
网上那种可在php4,5默认配置环境下运行的通用解析XML的PHP类,好像不多 至少我没找到,所以就写了这个,放上来大家讨论一下! 希望能得到各位宝贵的意见,并能完善此类! 我作了几个测试的路径! 大家可先看看效果! 源文件下载在下面!.... 为了大家看得方便,注释有点啰嗦了。 <?php /***************************************************************************** * xmlRead 类 * --------------------------------------------------------------- * 描述:XML文件数据读取类(SAX 解析) * 运行环境: PHP4,PHP5 最好有 iconv() 函数支持 * 用途: 用于读取xml文件数据到一数组里,目前还不能对一些特殊的标记进行处理 * 特点: 可为同级兄弟结点指定索引(数组下标) * ----------------------------------------------------------------- * 作者: Mayer * 邮箱: luck@21php.com * QQ号: 65712936 * 日期: 2005-01-16 16:29:00 * --------------------------------------------------------------------- * 所属团队: 中文PHP * 版权说明:本文件仅供测试,希望碰到任何问题或者有建议,能给原作者发 Email 反馈. * 在保留原作者和本说明的前提下,你可以任意使用,但作者没有义务做技术支持。 * 你可任意修改本文件,但必须保留头部的说明,同时希望能通知原作者你的改动。 * 测试地址: http://luck1314.com/mywork/xml_class.php?t=1 * http://luck1314.com/mywork/xml_class.php?t=2 * http://luck1314.com/mywork/xml_class.php?t=3 * http://luck1314.com/mywork/xml_class.php?t=4 * http://luck1314.com/mywork/xml_class.php?t=5 * 由于测试服务器不支持iconv函数所以第一个带中文标签的测试显示中文为乱码, * 而查看网页源码看是正常的,如大家知道解决的方法请告诉我。谢谢! * 测试时,大家看看各xml文件结构 * 讨论原帖: http://club.21php.com/showthread.php?p=34516#post34516 *****************************************************************************/ class xmlRead { //解析器 var $var_parser; //xml文件编码语言 var $var_lang = 'GB2312'; //***************************************************** // $var_node[深度][节点名] node_name // $var_node[深度][目标类型] target_type // $var_node[深度][目标名称] target_name // 目标: 属性/子节点; 0/1 // 深度: 数字 - by Mayer //***************************************************** var $var_node = array(); var $var_index = array(); var $var_stack = array(); //标记栈 var $var_stack_attrs = array(); //参数栈 //节点深度 var $var_depth = 0; // $var_data[深度]; $var_data[0] 用来存 xml文件所有记录 var $var_data = array(); //数据 function xmlRead($file,$node='',$lang) { if(is_array($node)) { $this->var_node = $node; } if($file) { if('UTF-8' == strtoupper($lang)) { $this->var_parser = xml_parser_create('UTF-8'); } else { $this->var_parser = xml_parser_create(); if('GBK' == strtoupper($lang)) { $this->var_lang = $lang; } } xml_set_object($this->var_parser,&$this); xml_parser_set_option($this->var_parser,XML_OPTION_CASE_FOLDING,0); xml_set_element_handler($this->var_parser,"startElement","endElement"); xml_set_character_data_handler($this->var_parser,"characterData"); $this->xmlRead_parser_file($file); } } /****************************************************** * 获取xml数据记录 -by Mayer 2005-1-17 ******************************************************/ function xmlRead_get_ret() { return $this->var_data[0]; } function xmlRead_parser_file($file) { if (!($fp = fopen($file,"r"))) { die("could not open XML input"); } $data = fread($fp,4096); if('GBK' == $this->var_lang) { //$data = str_replace(array('utf-8','gb2312','UTF-8','GB2312'),'GBK',$data); $data = preg_replace("/encoding=(.+)?>/",'encoding="GBK" ?>',$data); } elseif('UTF-8' == $this->var_lang) { } do { if(!xml_parse($this->var_parser,$data,feof($fp))) { die(sprintf("XML error: %s at line %d", xml_error_string(xml_get_error_code($this->var_parser)), xml_get_current_line_number($this->var_parser) ) ); } }while($data = fread($fp,4096)); xml_parser_free($this->var_parser); } function startElement($parser,$name,$attrs) { if(function_exists('iconv')) { $name = iconv('UTF-8',$this->var_lang,$name); } //节点开始,节点名入栈 array_push($this->var_stack,$name); array_push($this->var_stack_attrs,$attrs); //设置节点深度 $this->var_depth = count($this->var_stack) - 1; if($this->var_depth > 0) { //判断现在是否只有一个同级同名兄弟结点 // 当前深度标识的数据是否为一数组 && 是否存在同级同名索引为 $this->var_index[$this->var_depth][$name]] 的记录存在 // 或同级同名兄弟结点数据为字符串 if(is_array($this->var_data[$this->var_depth][$name]) && !isset($this->var_data[$this->var_depth][$name][$this->var_index[$this->var_depth][$name]]) || is_string($this->var_data[$this->var_depth][$name])) { //判断是否有索引设置 if($this->var_node[$this->var_depth]['node_name'] == $name) { //如果索引值不存在... if(!$this->var_index[$this->var_depth][$name]) { if(intval($this->var_node[$this->var_depth]['target_type']) == 1) { $index = $this->var_data[$this->var_depth][$name][$this->var_node[$this->var_depth]['target_name']]; if(is_array($index)) { $this->var_index[$this->var_depth][$name] = 0; } } else { $this->var_index[$this->var_depth][$name] = $attrs[$this->var_node[$this->var_depth]['target_name']]; } } } else { $this->var_index[$this->var_depth][$name] = 0; } $this->var_data[$this->var_depth][$name] = array($this->var_index[$this->var_depth][$name]=>$this->var_data[$this->var_depth][$name]); } } //检查节点类型, } function endElement($parser,$name) { if(function_exists('iconv')) { $name = iconv('UTF-8',$name); } //判断下级结点数据是否存在 if(is_array($this->var_data[$this->var_depth+1]) && count($this->var_data[$this->var_depth+1])) { //判断同级结点是否存在 如在标签结束时同级结点存在的话那在这级同名结点为多数 同级同名首结点在startElement里判断并重命名索引 //同级同名索引存在否 && 同级同名索引数据存在否 if(isset($this->var_index[$this->var_depth][$name]) && isset($this->var_data[$this->var_depth][$name][$this->var_index[$this->var_depth][$name]])) { //判断是否要设置结点索引 if($this->var_node[$this->var_depth]['node_name'] == $name) { if($this->var_node[$this->var_depth]['target_type'] == 0) { $attrs = end($this->var_stack_attrs); if(count($attrs)) { $index = $attrs[$this->var_node[$this->var_depth]['target_name']]; } } else { $index = $this->var_data[$this->var_depth+1][$this->var_node[$this->var_depth]['target_name']]; } $this->var_data[$this->var_depth][$name][$index] = $this->var_data[$this->var_depth+1]; } else { $this->var_data[$this->var_depth][$name][] = $this->var_data[$this->var_depth+1]; } } else { $this->var_data[$this->var_depth][$name] = $this->var_data[$this->var_depth+1]; //在还没有同级结点的时候,判断是否要设置索引 if($this->var_node[$this->var_depth]['node_name'] == $name) { if(intval($this->var_node[$this->var_depth]['target_type']) == 1) { $index = $this->var_data[$this->var_depth][$name][$this->var_node[$this->var_depth]['target_name']]; if(is_array($index)) { $index = 0; } } else { $attrs = end($this->var_stack_attrs); $index = $attrs[$this->var_node[$this->var_depth]['target_name']]; } //设置索引值 $this->var_index[$this->var_depth][$name] = $index; } else { //索引默认为 0 $this->var_index[$this->var_depth][$name] = 0; } } } unset($this->var_data[$this->var_depth+1]); unset($this->var_index[$this->var_depth+1]); //print_r($this->var_data[$this->var_depth][$name]); //echo " : $name<br>"; //节点结束,节点名出栈 array_pop($this->var_stack); array_pop($this->var_stack_attrs); $this->var_depth = count($this->var_stack) - 1; } function characterData($parser,$data) { if(trim($data) !== '') { $name = end($this->var_stack); if(function_exists('iconv')) { $data = iconv('UTF-8',$data); } //echo $data."<br>"; //判断是否已经有同级并同名的记录存在 if(is_array($this->var_data[$this->var_depth][$name])) { //判断是否要设置结点索引 if($this->var_node[$this->var_depth]['node_name'] == $name && $this->var_node[$this->var_depth]['target_type'] == 0) { $attrs = end($this->var_stack_attrs); if(count($attrs)) { $index = $attrs[$this->var_node[$this->var_depth]['target_name']]; } $this->var_data[$this->var_depth][$name][$index] = $data; } else { $this->var_data[$this->var_depth][$name][] = $data; } } else { $this->var_data[$this->var_depth][$name] = $data; //在还没有同级结点的时候,判断是否要设置索引 if($this->var_node[$this->var_depth]['node_name'] == $name && $this->var_node[$this->var_depth]['target_type'] == 0) { $attrs = end($this->var_stack_attrs); $index = $attrs[$this->var_node[$this->var_depth]['target_name']]; //设置索引值 $this->var_index[$this->var_depth][$name] = $index; } else { //索引默认为 0 $this->var_index[$this->var_depth][$name] = 0; } } } } } //------------------------ XMLREAD 类的用法如下 ------------------------------------------------------ $node = array(); switch($_REQUEST['t']) { case 1 : {//----解析编码为UTF-8格式的XML文件,标签为中文--------------------------------- $file = 'test_mod.xml'; $lang = 'UTF-8'; break; } case 2 : {//----解析编码为GB2312格式的XML文件------------------------------------------ $file = 'ex34.xml'; $lang = 'GB2312'; break; } case 3 : {//----解析含有GBK繁体字数据的XML文件------------------------------------------ $file = 'week_game.xml'; $lang = 'GBK'; break; } case 4 : {//----解析含有GBK繁体字数据的XML文件,并指定第2级名为m的结点的索引(数组下标)为其子结点i的值--- $file = 'week_game.xml'; $node[2] = array( 'node_name'=>'m', 'target_type'=>1, 'target_name'=>'i' ); $lang = 'GBK'; break; } case 5 : {//解析含有GBK繁体字数据的XML文件,并指定索引------------------------------------ $file = 'Europe_Full.xml'; $node[1] = array( 'node_name'=>'d', 'target_type'=>0, 'target_name'=>'d' ); $node[2] = array( 'node_name'=>'m', 'target_name'=>'i' ); $lang = 'GBK'; break; } default :{//--------------------------------------- $file = 'test_mod.xml'; $lang = 'UTF-8'; break; } } $xml = new xmlRead($file,$node,$lang); echo "<pre>"; print_r($xml->xmlRead_get_ret()); echo "</pre>"; ?> (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |