IT学习者 | 文章大全 | 技术文档 | 桌面壁纸 | 网络电台 | 成语 | 歇后语 | 站长导航 | 下载 | 周公解梦 | 生日密码 | 站长助手 | Flash | IP地址查询
 您现在的位置: IT学习者 >> 文章大全 >> 网络编程 >> PHP

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

【 作者:不在堕落    来源:网络  更新时间:2008-5-3 | 字体:
网上那种可在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>";
?>
相 关 文 章
相 关 软 件

音乐
嫁衣 画心 放生 天亮了 牡丹江 那滋味 擦肩而过 怀念过去 北京欢迎你 突然好想你 吻的太逼真 说好的幸福呢 坐上火车去拉萨 没有人比我更爱你
愚爱 心碎 稻香 带我走 醉赤壁 魔杰座 我还想她 明天过后 一定要爱你 等爱的玫瑰 原谅我一次 越单纯越幸福 最后一次的温柔 给我一首歌的时间
白狐 光荣 降临 下雨天 小酒窝 樱花草 恋爱新手 说唱脸谱 红色高跟鞋 寂寞才说爱 深深爱过你 爱上你是个错 即使知道要见面 不是因为寂寞才想你
城府 假如 花海 兰亭序 棉花糖 舍不得 最后一次 女人如烟 外滩十八号 我们的纪念 我们的无奈 心在跳情在烧 爱上你是我的错 爱情里没有谁对谁错
加入收藏留言建议自助友情链接普通友情链接站长的Blog
版权所有   COPYRIGHT 2002-2009 ★IT学习者★ ALL RIGHTS RESERVED.