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 表单验证实现代码
Mar 10 PHP
php dirname(__FILE__) 获取当前文件的绝对路径
Jun 28 PHP
PHP正则替换函数preg_replace和preg_replace_callback使用总结
Sep 22 PHP
微信公众平台开发关注及取消关注事件的方法
Dec 23 PHP
php提交表单发送邮件的方法
Mar 20 PHP
Symfony2开发之控制器用法实例分析
Feb 05 PHP
[原创]PHP字符串中插入子字符串方法总结
May 06 PHP
PHP的swoole扩展安装方法详细教程
May 18 PHP
php 变量引用与变量销毁机制详细介绍
Dec 05 PHP
使用Codeigniter重写insert的方法(推荐)
Mar 23 PHP
浅析PHP数据导出知识点
Feb 17 PHP
Laravel相关的一些故障解决
Aug 19 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 Class&amp;Object -- 解析PHP实现二叉树
2013/06/25 PHP
PHP结合JQueryJcrop实现图片裁切实例详解
2014/07/24 PHP
Laravel框架数据库CURD操作、连贯操作总结
2014/09/03 PHP
PHP静态延迟绑定和普通静态效率的对比
2017/10/20 PHP
PHP实现字符串翻转功能的方法【递归与循环算法】
2017/11/03 PHP
TNC vs RR BO3 第一场 2.14
2021/03/10 DOTA
仅IE6/7/8中innerHTML返回值忽略英文空格的问题
2011/04/07 Javascript
javascript动态的改变IFrame的高度实现自动伸展
2013/10/12 Javascript
Jquery 类网页微信二维码图块滚动效果具体实现
2013/10/14 Javascript
javascript检测浏览器的缩放状态实现代码
2014/09/28 Javascript
JS实现鼠标点击展开或隐藏表格行的方法
2015/03/03 Javascript
JavaScript动态改变表格单元格内容的方法
2015/03/30 Javascript
原生js实现类似弹窗抖动效果
2015/04/02 Javascript
JavaScript字符串删除重复字符的方法
2015/12/25 Javascript
javascript事件的传播基础实例讲解(35)
2017/02/14 Javascript
vue-resource 拦截器使用详解
2017/02/21 Javascript
vue父组件点击触发子组件事件的实例讲解
2018/02/08 Javascript
Vue组件开发技巧总结
2018/03/04 Javascript
jQuery实现数字自动增加或者减少的动画效果示例
2018/12/11 jQuery
[01:14]2014DOTA2展望TI 剑指西雅图newbee战队专访
2014/06/30 DOTA
[03:10]2014DOTA2 TI马来劲旅Titan首战告捷目标只是8强
2014/07/10 DOTA
python将.ppm格式图片转换成.jpg格式文件的方法
2018/10/27 Python
pytorch 彩色图像转灰度图像实例
2020/01/13 Python
Tensorflow矩阵运算实例(矩阵相乘,点乘,行/列累加)
2020/02/05 Python
python框架flask入门之环境搭建及开启调试
2020/06/07 Python
Python调用C/C++的方法解析
2020/08/05 Python
python实现数学模型(插值、拟合和微分方程)
2020/11/13 Python
HTML5的hidden属性兼容老浏览器的方法
2014/04/23 HTML / CSS
护理专业学生的求职信范文
2013/12/11 职场文书
优秀毕业生自荐信范文
2014/01/01 职场文书
高中美术教学反思
2014/01/19 职场文书
《愚公移山》教学反思
2014/02/20 职场文书
运动会广播稿150字(9篇)
2014/09/20 职场文书
房屋产权证明书
2015/06/19 职场文书
《法国号》教学反思
2016/02/22 职场文书
解决spring.thymeleaf.cache=false不起作用的问题
2022/06/10 Java/Android