IT学习者 | 文章大全 | 技术文档 | 桌面壁纸 | 实用查询 | 网络电台 | 成语 | 歇后语 | 网址 | 下载 | 周公解梦 | 生日密码 | 电视剧365 | Flash
 您现在的位置: 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-2008 ★IT学习者★ ALL RIGHTS RESERVED.