IT学习者 | 站长学院 | 技术文档 | 成语 | 歇后语 | 桌面壁纸 | 天气预报 | 帝国时代 | 生日密码 | 代码收藏 | 厦门天气 | IP地址查询 | 生活百科

通用XML文件数据解析的PHP类

【 来源:网络 作者:不在堕落 更新时间:2008-05-03 | 字体:
网上那种可在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', $this->var_lang, $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', $this->var_lang, $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_type'=>1,
'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>";
?>
  • 转载请注明来源:IT学习者 网址:http://www.itlearner.com/ 向您的朋友推荐此文章
  • 文章关键词:  XML  解析 
  • 特别声明: 本站除部分特别声明禁止转载的专稿外的其他文章可以自由转载,但请务必注明出处和原始作者。文章版权归文章原始作者所有。对于被本站转载文章的个人和网站,我们表示深深的谢意。如果本站转载的文章有版权问题请联系我们,我们会尽快予以更正。
RSS订阅
  • 抓虾
  • google reader
  • 鲜果
  • QQ邮箱

音乐
犯贱 月光 包容 想你了 甩葱歌 黄梅戏 爱情错觉 星月神话 这就是爱 最幸福的人 爱笑的眼睛 321对不起 你不知道的事 看透爱情看透你 你还欠我一个拥抱
忐忑 爱过 浮夸 猜不透 洛丽塔 错的人 爱情买卖 和平分手 等你爱我 没那么简单 我的心好冷 姑娘我爱你 在回忆中死去 我的爱情不见了 你在我心中是最美
她说 偏爱 素颜 错错错 走天涯 套马杆 断桥残雪 爱是你我 郎的诱惑 客官不可以 我要去西藏 我的好兄弟 哥只是个传说 情歌没有告诉你 我和草原有个约定
天真 王妃 小三 爱琴海 要抱抱 单身歌 埋葬冬天 给力青春 荷塘月色 最好不相见 最炫民族风 新贵妃醉酒 贝多芬的悲伤 大笑江湖主题曲 给我一个理由忘记
加入收藏留言建议ASP探针PHP探针站长Enjoy的BlogAboutDomain
© 2010 IT学习者 - itlearner.com
RunTime:49.02ms