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.NET的入门教程
Oct 09 PHP
PHP使用imagick读取PDF生成png缩略图的两种方法
Mar 20 PHP
ThinkPHP应用模式扩展详解
Jul 16 PHP
php Imagick获取图片RGB颜色值
Jul 28 PHP
php实现的常见排序算法汇总
Sep 08 PHP
安装ImageMagick出现error while loading shared libraries的解决方法
Sep 23 PHP
php操作xml入门之xml标签的属性分析
Jan 23 PHP
joomla数据库操作示例代码
Jan 06 PHP
php简单截取字符串代码示例
Oct 19 PHP
PHP折半(二分)查找算法实例分析
May 12 PHP
Laravel 添加多语言提示信息的方法
Sep 29 PHP
Laravel ORM 数据model操作教程
Oct 21 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中将地址生成迅雷快车旋风链接的代码[测试通过]
2011/04/20 PHP
php约瑟夫问题解决关于处死犯人的算法
2015/03/23 PHP
基于 Swoole 的微信扫码登录功能实现代码
2018/01/15 PHP
PHP实现将上传图片自动缩放到指定分辨率,并保持清晰度封装类示例
2019/06/17 PHP
ThinkPHP框架结合Ajax实现用户名校验功能示例
2019/07/03 PHP
javascript loadScript异步加载脚本示例讲解
2013/11/14 Javascript
js判断鼠标左、中、右键哪个被点击的方法
2015/01/27 Javascript
跟我学习javascript的undefined与null
2015/11/17 Javascript
基于jQuery的AJAX和JSON实现纯html数据模板
2016/08/09 Javascript
js弹出窗口简单实现代码
2017/03/22 Javascript
jQuery动态追加页面数据以及事件委托详解
2017/05/06 jQuery
node.js中cluster的使用教程
2017/06/09 Javascript
js轮播图的插件化封装详解
2017/07/17 Javascript
使用express搭建一个简单的查询服务器的方法
2018/02/09 Javascript
微信小程序实现图片上传功能
2018/05/28 Javascript
js实现左右两侧浮动广告
2018/07/09 Javascript
支付宝小程序tabbar底部导航
2018/11/06 Javascript
vue 封装 Adminlte3组件的实现
2020/03/18 Javascript
如何在微信小程序中使用骨架屏的步骤
2020/06/12 Javascript
[01:38]DOTA2辉夜杯 欢乐的观众现场采访
2015/12/26 DOTA
[44:40]2018DOTA2亚洲邀请赛3月30日 小组赛A组Liquid VS OG
2018/03/31 DOTA
[00:15]TI9地铁玩家打卡
2019/08/11 DOTA
[54:15]DOTA2-DPC中国联赛 正赛 DLG vs Dragon BO3 第二场2月1日
2021/03/11 DOTA
Python编程把二叉树打印成多行代码
2018/01/04 Python
python函数与方法的区别总结
2019/06/23 Python
对python中url参数编码与解码的实例详解
2019/07/25 Python
利用python3筛选excel中特定的行(行值满足某个条件/行值属于某个集合)
2020/09/04 Python
python rsa-oaep加密的示例代码
2020/09/23 Python
CSS实现的一闪而过的图片闪光效果
2014/04/23 HTML / CSS
印尼最大的在线购物网站:MatahariMall.com
2016/08/26 全球购物
就业推荐表自我鉴定
2014/03/21 职场文书
群众路线剖析材料(四风问题)
2014/10/08 职场文书
社区元宵节活动总结
2015/02/06 职场文书
六年级情感作文之500字
2019/10/23 职场文书
java设计模式--七大原则详解
2021/07/21 Java/Android
Android基于Fresco实现圆角和圆形图片
2022/04/01 Java/Android