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(3)
Oct 09 PHP
杏林同学录(三)
Oct 09 PHP
PHP新手上路(二)
Oct 09 PHP
Linux下手动编译安装PHP扩展的例子分享
Jul 15 PHP
PHP JSON格式的中文显示问题解决方法
Apr 09 PHP
PHP中使用curl入门教程
Jul 02 PHP
PHP读取PPT文件的方法
Dec 10 PHP
php判断邮箱地址是否存在的方法
Feb 13 PHP
PHP加密解密类实例代码
Jul 20 PHP
php pdo操作数据库示例
Mar 10 PHP
PHP的反射机制实例详解
Mar 29 PHP
thinkphp框架实现路由重定义简化url访问地址的方法分析
Apr 04 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
php4的彩蛋
2006/10/09 PHP
php error_log 函数的使用
2009/04/13 PHP
php侧拉菜单 漂亮,可以向右或者向左展开,支持FF,IE
2009/10/15 PHP
yii框架builder、update、delete使用方法
2014/04/30 PHP
一款简单实用的php操作mysql数据库类
2014/12/08 PHP
php生成动态验证码gif图片
2015/10/19 PHP
PHP重置数组为连续数字索引的几种方式总结
2018/03/12 PHP
jQueryUI写一个调整分类的拖放效果实现代码
2012/05/10 Javascript
JavaScript实现把rgb颜色转换成16进制颜色的方法
2015/06/01 Javascript
jQuery无刷新分页完整实例代码
2015/10/27 Javascript
jquery自定义表格样式
2015/11/23 Javascript
js实现三级联动效果(简单易懂)
2017/03/27 Javascript
JS创建Tag标签的方法详解
2017/06/09 Javascript
JavaScript实现树的遍历算法示例【广度优先与深度优先】
2017/10/26 Javascript
jQuery实现的页面详情展开收起功能示例
2018/06/11 jQuery
jQuery实现仿京东防抖动菜单效果示例
2018/07/06 jQuery
Element PageHeader页头的使用方法
2020/07/26 Javascript
vue mvvm数据响应实现
2020/11/11 Javascript
如何在vue中使用video.js播放m3u8格式的视频
2021/02/01 Vue.js
Python基于Tkinter的HelloWorld入门实例
2015/06/17 Python
Python 序列的方法总结
2016/10/18 Python
python with提前退出遇到的坑与解决方案
2018/01/05 Python
python3+pyqt5+itchat微信定时发送消息的方法
2019/02/20 Python
Python3 A*寻路算法实现方式
2019/12/24 Python
python 实现在无序数组中找到中位数方法
2020/03/03 Python
CSS3实现鼠标悬停显示扩展内容
2016/08/24 HTML / CSS
联想西班牙官网:Lenovo西班牙
2018/08/28 全球购物
工程造价管理专业大专生求职信
2013/10/06 职场文书
网络优化专员求职信
2014/05/04 职场文书
公司应聘求职信
2014/06/21 职场文书
高二学年自我鉴定范文(2篇)
2014/09/26 职场文书
施工安全协议书范本
2014/09/26 职场文书
教师查摆问题及整改措施
2014/10/11 职场文书
公司财务部岗位职责
2015/04/14 职场文书
房产销售员2015年终工作总结
2015/10/22 职场文书
仅用一句SQL更新整张表的涨跌幅、涨跌率的解决方案
2021/05/06 MySQL