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 相关文章推荐
Extended CHM PHP 语法手册之 DIY
Oct 09 PHP
PHP伪静态页面函数附使用方法
Jun 20 PHP
php下使用SimpleXML 处理XML 文件
Feb 27 PHP
用PHP获取Google AJAX Search API 数据的代码
Mar 12 PHP
php设计模式 Delegation(委托模式)
Jun 26 PHP
PHP在线生成二维码代码(google api)
Jun 03 PHP
php修改NetBeans默认字体的大小
Jul 02 PHP
PHP运行SVN命令显示某用户的文件更新记录的代码
Jan 03 PHP
php 购物车完整实现代码
Jun 05 PHP
图文介绍PHP添加Redis模块及连接
Jul 28 PHP
windows7配置Nginx+php+mysql的详细教程
Sep 04 PHP
php设计模式之中介者模式分析【星际争霸游戏案例】
Mar 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程序实现支持页面后退的两种方法
2008/06/30 PHP
PHP二维数组排序简单实现方法
2016/02/14 PHP
Laravel开启跨域请求的方法
2019/10/13 PHP
jquery获取下拉列表的值为null的解决方法
2011/03/18 Javascript
jQuery 源码分析笔记(3) Deferred机制
2011/06/19 Javascript
EasyUI 中 MenuButton 的使用方法
2012/07/14 Javascript
基于jquery实现省市联动效果
2015/11/23 Javascript
实例详解JSON数据格式及json格式数据域字符串相互转换
2016/01/07 Javascript
EXT中单击button按钮grid添加一行(光标位置可设置)的实例代码
2016/06/02 Javascript
jQuery动态加载css文件实现方法
2016/06/15 Javascript
在vue中获取dom元素内容的方法
2017/07/10 Javascript
vue loadmore组件上拉加载更多功能示例代码
2017/07/19 Javascript
vue单页面打包文件大?首次加载慢?nginx带你飞,从7.5M到1.3M蜕变过程(推荐)
2018/01/16 Javascript
jQuery实现简单复制json对象和json对象集合操作示例
2018/07/09 jQuery
webpack4.x开发环境配置详解
2018/08/04 Javascript
当vue路由变化时,改变导航栏的样式方法
2018/08/22 Javascript
JS实现的自定义map方法示例
2019/05/17 Javascript
python获得文件创建时间和修改时间的方法
2015/06/30 Python
Python入门_学会创建并调用函数的方法
2017/05/16 Python
Python MySQL数据库连接池组件pymysqlpool详解
2017/07/07 Python
Python基于OpenCV实现视频的人脸检测
2018/01/23 Python
基于python3 OpenCV3实现静态图片人脸识别
2018/05/25 Python
Python pandas.DataFrame调整列顺序及修改index名的方法
2019/06/21 Python
python单例模式的多种实现方法
2019/07/26 Python
关于pytorch多GPU训练实例与性能对比分析
2019/08/19 Python
python+Django实现防止SQL注入的办法
2019/10/31 Python
matplotlib 曲线图 和 折线图 plt.plot()实例
2020/04/17 Python
使用PyCharm安装pytest及requests的问题
2020/07/31 Python
html5 拖拽及用 js 实现拖拽功能的示例代码
2020/10/23 HTML / CSS
美国购买韩国护肤和美容产品网站:Althea Korea
2020/11/16 全球购物
乒乓球兴趣小组活动总结
2014/07/08 职场文书
车辆年检委托书范本
2014/10/14 职场文书
简单租房协议书
2014/10/21 职场文书
护士自我推荐信范文
2015/03/24 职场文书
2015年班级工作总结范文
2015/04/03 职场文书
Java数据结构之链表相关知识总结
2021/06/18 Java/Android