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 相关文章推荐
php5 non-thread-safe和thread-safe这两个版本的区别分析
Mar 13 PHP
PHP实现时间轴函数代码
Oct 08 PHP
Zend的MVC机制使用分析(一)
May 02 PHP
spl_autoload_register与autoload的区别详解
Jun 03 PHP
浅谈php中mysql与mysqli的区别分析
Jun 10 PHP
PHP中使用xmlreader读取xml数据示例
Dec 29 PHP
PHP使用curl函数发送Post请求的注意事项
Nov 26 PHP
php curl 模拟登录并获取数据实例详解
Dec 22 PHP
Laravel 5.5基于内置的Auth模块实现前后台登陆详解
Dec 21 PHP
PHP Include文件实例讲解
Feb 15 PHP
PHP+mysql防止SQL注入的方法小结
Apr 27 PHP
laravel5.6实现数值转换
Oct 23 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
上海永华YH-R296(华普R-96)12波段立体声收音机的分析和打理
2021/03/02 无线电
PHP中在数据库中保存Checkbox数据(1)
2006/10/09 PHP
PHP脚本的10个技巧(1)
2006/10/09 PHP
function.inc.php超越php
2006/12/09 PHP
php中比较简单的导入phpmyadmin生成的sql文件的方法
2011/06/28 PHP
深入解析php之sphinx
2013/05/15 PHP
php获取QQ头像并显示的方法
2014/12/23 PHP
Yii2.0多文件上传实例说明
2017/07/24 PHP
PHP lcfirst()函数定义与用法
2019/03/08 PHP
通过Mootools 1.2来操纵HTML DOM元素
2009/09/15 Javascript
页面定时刷新(1秒刷新一次)
2013/11/22 Javascript
JavaScript知识点整理
2015/12/09 Javascript
Javascript基于对象三大特性(封装性、继承性、多态性)
2016/01/04 Javascript
React Js 微信禁止复制链接分享禁止隐藏右上角菜单功能
2017/05/26 Javascript
webpack3里使用uglifyjs压缩js时打包报错的解决
2018/12/13 Javascript
微信小程序获取用户信息并保存登录状态详解
2019/05/10 Javascript
js实现九宫格抽奖
2020/03/19 Javascript
[00:34]DOTA2上海特级锦标赛 VG战队宣传片
2016/03/04 DOTA
python抓取网页时字符集转换问题处理方案分享
2014/06/19 Python
Python获取任意xml节点值的方法
2015/05/05 Python
Python的time模块中的常用方法整理
2015/06/18 Python
Python中pandas模块DataFrame创建方法示例
2018/06/20 Python
Falsk 与 Django 过滤器的使用与区别详解
2019/06/04 Python
在django中使用post方法时,需要增加csrftoken的例子
2020/03/13 Python
Html5游戏开发之乒乓Ping Pong游戏示例(三)
2013/01/21 HTML / CSS
HTML5 canvas绘制的玫瑰花效果
2014/05/29 HTML / CSS
Zavvi荷兰:英国大型音像制品和图书游戏零售商
2018/03/22 全球购物
LN-CC中国:高端男装和女装的奢侈时尚目的地
2019/09/14 全球购物
意大利网上购书网站:Libraccio.it
2021/02/03 全球购物
.net面试题
2015/12/22 面试题
热能动力工程毕业生自荐信
2013/11/07 职场文书
自荐书范文
2013/12/08 职场文书
给面试官的感谢信
2014/02/01 职场文书
运输服务质量承诺书
2014/03/27 职场文书
教师三严三实学习心得体会
2014/10/11 职场文书
论语读书笔记
2015/06/26 职场文书