PHP用SAX解析XML的实现代码与问题分析


Posted in PHP onAugust 22, 2011
<?php 
$g_books = array(); 
$g_elem = null; 
function startElement( $parser, $name, $attrs ) 
{ 
global $g_books, $g_elem; 
if ( $name == 'BOOK' ) $g_books []= array(); 
$g_elem = $name; 
} 
function endElement( $parser, $name ) 
{ 
global $g_elem; 
$g_elem = null; 
} 
function textData( $parser, $text ) 
{ 
global $g_books, $g_elem; 
if ( $g_elem == 'AUTHOR' || 
$g_elem == 'PUBLISHER' || 
$g_elem == 'TITLE' ) 
{ 
$g_books[ count( $g_books ) - 1 ][ $g_elem ] = $text; 
} 
} 
$parser = xml_parser_create(); 
xml_set_element_handler( $parser, "startElement", "endElement" ); 
xml_set_character_data_handler( $parser, "textData" ); 
$f = fopen( 'books.xml', 'r' ); 
while( $data = fread( $f, 4096 ) ) 
{ 
xml_parse( $parser, $data ); 
} 
xml_parser_free( $parser ); 
foreach( $g_books as $book ) 
{ 
echo $book['TITLE']." - ".$book['AUTHOR']." - "; 
echo $book['PUBLISHER']."\n"; 
} 
?>

PHP中用SAX方式解析XML发现的问题
XML如下:
so.xml
<?xml version="1.0" encoding="GBK"?> 
<result> 
<row> 
<id>1047869</id> 
<date>2008-08-28 14:54:51</date> 
<title>红花还需绿叶扶--浅谈脚架云台的选购</title> 
<summary>很多专业摄影师在选购三脚架的时候,往往出手阔绰,3、4000元一个的捷信或者曼富图三脚架常常不用经过思考就买下来了,可是,他们却总是忽视了云台的精挑细眩其实,数码相机架在三脚架上面究竟稳不稳,起决定作用的是云台,那么我们如何才能挑选到一款稳如磐石的云台呢?云台家族种类繁多用途迥异简单的说,脚架云台是用于连接相机与脚架进行角度调节的部件,主要分成三维云台和球型云台。三维云台在横向旋转</summary> 
</row> 
...(省略若干行) 
</result>

xml_class.php
<?php 
class xml { 
var $parser; 
var $i =0; 
var $search_result = array(); 
var $row = array(); 
var $data = array(); 
var $now_tag; 
var $tags = array("ID", "CLASSID", "SUBCLASSID", "CLASSNAME", "TITLE", "SHORTTITLE", "AUTHOR", "PRODUCER", "SUMMARY", "CONTENT", "DATE"); 
function xml() 
{ 
$this->parser = xml_parser_create(); 
xml_set_object($this->parser, $this); 
xml_set_element_handler($this->parser, "tag_open", "tag_close"); 
xml_set_character_data_handler($this->parser, "cdata"); 
} 
function parse($data) 
{ 
xml_parse($this->parser, $data); 
} 
function tag_open($parser, $tag, $attributes) 
{ 
$this->now_tag=$tag; 
if($tag=='RESULT') { 
$this->search_result = $attributes; 
} 
if($tag=='ROW') { 
$this->row[$this->i] = $attributes; 
} 
} 
function cdata($parser, $cdata) 
{ 
if(in_array($this->now_tag, $this->tags)){ 
$tagname = strtolower($this->now_tag); 
$this->data[$this->i][$tagname] = $cdata; 
} 
} 
function tag_close($parser, $tag) 
{ 
$this->now_tag=""; 
if($tag=='ROW') { 
$this->i++; 
} 
} 
} 
?>

search.php
<?php 
require_once("./xml_class.php"); 
$xml = file_get_contents("./so.xml"); 
$xml_parser = new xml(); 
$xml_parser->parse($xml); 
print_r($xml_parser); 
?>

最后得到的结果中summary中的数据少了很多,总是得不到完整的summary内容。有时还会得到乱码,在网上也找了半天也不知道是什么问题引起的。

后来才发现问题是因为xml_parser解析XML是循环处理节点中的数据的,每次只取大概300个字符长度(具体是多少,我也不太清楚,只是用strlen输出大概在300左右),于是才知道是因为每次的循环就会把前次的数据给复盖了,这样就会出现数据不全的问题。

解决办法就是把xml_class文件中的xml类中的cdata方法中$this->data[$this->i][$tagname] = $cdata;改为$this->data[$this->i][$tagname] .= $cdata;即可解决(其中有一些NOTICE错误,PHP已忽略了).

PHP 相关文章推荐
使用php来实现网络服务
Sep 15 PHP
php获取post中的json数据的实现方法
Jun 08 PHP
Zend的AutoLoad机制介绍
Sep 27 PHP
php自动加载autoload机制示例分享
Feb 20 PHP
php获取四位字母和数字的随机数的实现方法
Jan 09 PHP
PHP获取POST数据的几种方法汇总
Mar 03 PHP
php使用curl简单抓取远程url的方法
Mar 13 PHP
百度工程师讲PHP函数的实现原理及性能分析(二)
May 13 PHP
Yii2框架使用计划任务的方法
May 25 PHP
PHP实现的下载远程文件类定义与用法示例
Jul 05 PHP
php微信分享到朋友圈、QQ、朋友、微博
Feb 18 PHP
PHP中将一个字符串部分字符用星号*替代隐藏的实现代码
Sep 08 PHP
PHP IF ELSE简化/三元一次式的使用
Aug 22 #PHP
PHP表单验证的3个函数ISSET()、empty()、is_numeric()的使用方法
Aug 22 #PHP
phpmyadmin安装时提示:Warning: require_once(./libraries/common.inc.php)错误解决办法
Aug 18 #PHP
PHP-CGI进程CPU 100% 与 file_get_contents 函数的关系分析
Aug 15 #PHP
11个PHP 分页脚本推荐
Aug 15 #PHP
PHP版国家代码、缩写查询函数代码
Aug 14 #PHP
PHP动态创建Web站点的方法
Aug 14 #PHP
You might like
基于PHP导出Excel的小经验 完美解决乱码问题
2013/06/10 PHP
使用Smarty 获取当前日期时间和格式化日期时间的方法详解
2013/06/18 PHP
thinkphp多层MVC用法分析
2015/12/30 PHP
php base64 编码与解码实例代码
2017/03/21 PHP
PHP7.0连接DB操作实例分析【基于mysqli】
2019/09/26 PHP
Windows服务器中PHP如何安装redis扩展
2019/09/27 PHP
jquery miniui 教程 表格控件 合并单元格应用
2012/11/25 Javascript
javascript和jquery修改a标签的href属性
2013/12/16 Javascript
Javascript 函数parseInt()转换时出现bug问题
2014/05/20 Javascript
Javascript Objects详解
2014/09/04 Javascript
浅谈jquery之on()绑定事件和off()解除绑定事件
2016/10/26 Javascript
js基础之DOM中document对象的常用属性方法详解
2016/10/28 Javascript
Form表单上传文件(type=&quot;file&quot;)的使用
2017/08/03 Javascript
详解各版本React路由的跳转的方法
2018/05/10 Javascript
vue-quill-editor富文本编辑器简单使用方法
2018/09/21 Javascript
nodejs通过钉钉群机器人推送消息的实现代码
2019/05/05 NodeJs
一起写一个即插即用的Vue Loading插件实现
2019/10/31 Javascript
Python sys.argv用法实例
2015/05/28 Python
Python实现利用163邮箱远程关电脑脚本
2018/02/22 Python
python实现雨滴下落到地面效果
2018/06/21 Python
Python 爬虫之Beautiful Soup模块使用指南
2018/07/05 Python
Python爬虫之pandas基本安装与使用方法示例
2018/08/08 Python
Django logging配置及使用详解
2019/07/23 Python
Django 通过JS实现ajax过程详解
2019/07/30 Python
python 多进程队列数据处理详解
2019/12/23 Python
手把手教你安装Windows版本的Tensorflow
2020/03/26 Python
Joules美国官网:出色的英国风格
2017/10/30 全球购物
Merrell美国官网:美国登山运动鞋品牌
2018/02/07 全球购物
乔丹名人堂演讲稿
2014/05/24 职场文书
2014年资料员工作总结
2014/11/18 职场文书
楚门的世界观后感
2015/06/03 职场文书
社区服务理念口号
2015/12/25 职场文书
Python代码,能玩30多款童年游戏!这些有几个是你玩过的
2021/04/27 Python
Django migrate报错的解决方案
2021/05/20 Python
浅谈JavaScript浅拷贝和深拷贝
2021/11/07 Javascript
MySQL中优化SQL语句的方法(show status、explain分析服务器状态信息)
2022/04/09 MySQL