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+Mysql日期时间如何转换(UNIX时间戳和格式化日期)
Jul 15 PHP
php设计模式小结
Feb 15 PHP
简单的php文件上传(实例)
Oct 27 PHP
zend framework框架中url大小写问题解决方法
Aug 19 PHP
Javascript与PHP验证用户输入URL地址是否正确
Oct 09 PHP
PHP与Ajax相结合实现登录验证小Demo
Mar 16 PHP
PHP+mysql实现从数据库获取下拉树功能示例
Jan 06 PHP
CodeIgniter框架基本增删改查操作示例
Mar 23 PHP
Windows下php+mysql5.7配置教程
May 16 PHP
PHP在弹框中获取foreach中遍历的id值并传递给地址栏
Jun 13 PHP
深入理解Yii2.0乐观锁与悲观锁的原理与使用
Jul 26 PHP
php获取ajax的headers方法与内容实例
Dec 27 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判断当前操作系统类型
2015/10/28 PHP
详解配置 Apache 服务器支持 PHP 文件的解析
2017/02/15 PHP
PHP结合jquery ajax实现上传多张图片,并限制图片大小操作示例
2019/03/01 PHP
php设计模式之适配器模式实例分析【星际争霸游戏案例】
2020/04/07 PHP
JQuery 初体验(建议学习jquery)
2009/04/25 Javascript
通过JS获取用户本地图片路径并显示的代码
2012/02/16 Javascript
自己编写的类似JS的trim方法
2013/10/09 Javascript
Extjs4中的分页应用结合前后台
2013/12/13 Javascript
Seajs的学习笔记
2014/03/04 Javascript
js纯数字逐一停止显示效果的实现代码
2016/03/16 Javascript
js获取当前年月日-YYYYmmDD格式的实现代码
2016/06/01 Javascript
项目实践一图片上传之form表单还是base64前端图片压缩(前端图片压缩)
2016/07/28 Javascript
Node.js中使用jQuery的做法
2016/08/17 Javascript
webstorm中配置Eslint的两种方式及差异比较详解
2018/10/19 Javascript
element实现合并单元格通用方法
2019/11/13 Javascript
Element Rate 评分的使用方法
2020/07/27 Javascript
浅析 Vue 3.0 的组装式 API(一)
2020/08/31 Javascript
微信小程序实现通讯录列表展开收起
2020/11/18 Javascript
用Python脚本生成Android SALT扰码的方法
2013/09/18 Python
Python中的数据对象持久化存储模块pickle的使用示例
2016/03/03 Python
python里dict变成list实例方法
2019/06/26 Python
PyQt5基本控件使用详解:单选按钮、复选框、下拉框
2019/08/05 Python
利用matplotlib实现根据实时数据动态更新图形
2019/12/13 Python
医务人员竞聘职务自我评价分享
2013/11/08 职场文书
护理专业学生的求职信范文
2013/12/11 职场文书
信息技术专业个人自我评价
2013/12/11 职场文书
迟到检讨书大全
2014/01/25 职场文书
幼儿教师国培感言
2014/02/19 职场文书
环保倡议书300字
2014/05/15 职场文书
公司证明怎么写
2014/09/22 职场文书
经营目标责任书
2015/05/08 职场文书
盗窃案辩护词
2015/05/21 职场文书
房屋质量投诉书
2015/07/02 职场文书
2016年社会主义核心价值观心得体会
2016/01/21 职场文书
创业计划书详解
2019/07/19 职场文书
Windows Server 2008 修改远程登录端口以及配置防火墙
2022/04/28 Servers