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 $_ENV为空的原因分析
Jun 01 PHP
php图片的裁剪与缩放生成符合需求的缩略图
Jan 11 PHP
jQuery中的RadioButton,input,CheckBox取值赋值实现代码
Feb 18 PHP
PHP实现加密的几种方式介绍
Feb 22 PHP
PHP输出日历表代码实例
Mar 27 PHP
PHP开发中AJAX技术的简单应用
Dec 11 PHP
详解PHP中websocket的使用方法
Sep 15 PHP
php实现留言板功能(代码详解)
Mar 28 PHP
smarty模板的使用方法实例分析
Sep 18 PHP
使用tp框架和SQL语句查询数据表中的某字段包含某值
Oct 18 PHP
laravel model 两表联查示例
Oct 24 PHP
ThinkPHP5与单元测试PHPUnit使用详解
Feb 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
PHP 数组遍历方法大全(foreach,list,each)
2010/06/30 PHP
深入php self与$this的详解
2013/06/08 PHP
使用php将某个目录下面的所有文件罗列出来的方法详解
2013/06/21 PHP
PHP使用MPDF类生成PDF的方法
2015/12/08 PHP
syntaxhighlighter 使用方法
2007/07/02 Javascript
JavaScript入门教程(1) 什么是JS
2009/01/31 Javascript
JavaScript flash复制库类 Zero Clipboard
2011/01/17 Javascript
整理一些JavaScript的IE和火狐的兼容性注意事项
2011/03/17 Javascript
Javascript 拖拽雏形(逐行分析代码,让你轻松了拖拽的原理)
2015/01/23 Javascript
JavaScript编程中容易出BUG的几点小知识
2015/01/31 Javascript
JS限制文本框只能输入数字和字母方法
2015/02/28 Javascript
DEDECMS如何为文章添加HOT NEW标志图片
2015/08/14 Javascript
详解angularjs结合pagination插件实现分页功能
2017/02/10 Javascript
基于es6三点运算符的使用方法(实例讲解)
2017/10/12 Javascript
微信小程序scroll-view仿拼多多横向滑动滚动条
2020/04/21 Javascript
mocha的时序规则讲解
2019/02/16 Javascript
Layui数据表格 前后端json数据接收的方法
2019/09/19 Javascript
python计算书页码的统计数字问题实例
2014/09/26 Python
Python简单计算文件MD5值的方法示例
2018/04/11 Python
Python实现八皇后问题示例代码
2018/12/09 Python
python+selenium实现QQ邮箱自动发送功能
2019/01/23 Python
django模板加载静态文件的方法步骤
2019/03/01 Python
Python 存储字符串时节省空间的方法
2019/04/23 Python
Python统计一个字符串中每个字符出现了多少次的方法【字符串转换为列表再统计】
2019/05/05 Python
Python 格式化输出_String Formatting_控制小数点位数的实例详解
2020/02/04 Python
python库skimage给灰度图像染色的方法示例
2020/04/27 Python
关于探究python中sys.argv时遇到的问题详解
2021/02/23 Python
Unix如何在一行中运行多个命令
2015/05/29 面试题
高中微机老师自我鉴定
2014/02/16 职场文书
元旦促销方案
2014/03/15 职场文书
2014年售后服务工作总结
2014/11/18 职场文书
2014年度思想工作总结
2014/11/27 职场文书
圣诞晚会主持词开场白
2015/05/28 职场文书
Win11安装升级时提示“该电脑必须支持安全启动”
2022/04/19 数码科技
提高系统的吞吐量解决数据库重复写入问题
2022/04/23 MySQL
MySQL聚簇索引和非聚簇索引的区别详情
2022/06/14 MySQL