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 相关文章推荐
应用开发中涉及到的css和php笔记分享
Aug 02 PHP
Sorting Array Values in PHP(数组排序)
Sep 15 PHP
有关PHP中MVC的开发经验分享
May 17 PHP
PHP中常用的输出函数总结
Sep 22 PHP
初识Laravel
Oct 30 PHP
PHP制作万年历
Jan 07 PHP
php实现简单的MVC框架实例
Sep 23 PHP
PHP使用strtotime获取上个月、下个月、本月的日期
Dec 30 PHP
PHP基于单例模式实现的mysql类
Jan 09 PHP
php无限级评论嵌套实现代码
Apr 18 PHP
PHP检查文件是否存在,不存在自动创建及读取文件内容操作示例
Jan 23 PHP
浅谈PHP之ThinkPHP框架使用详解
Jul 21 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和Mysqlweb应用开发核心技术 第1部分 Php基础-3 代码组织和重用2
2011/07/03 PHP
Laravel+jQuery实现AJAX分页效果
2016/09/14 PHP
php过滤htmlspecialchars() 函数实现把预定义的字符转换为 HTML 实体用法分析
2019/06/25 PHP
JavaScript 异步调用框架 (Part 5 - 链式实现)
2009/08/04 Javascript
在VS2008中使用jQuery智能感应的方法
2010/12/30 Javascript
20款非常优秀的 jQuery 工具提示插件 推荐
2012/07/15 Javascript
在javaScript中关于submit和button的区别介绍
2013/10/20 Javascript
关于页面嵌入swf覆盖div层的问题的解决方法
2014/02/11 Javascript
JavaScript中DOM详解
2015/04/13 Javascript
使用impress.js制作幻灯片
2015/09/09 Javascript
jQuery控制li上下循环滚动插件用法实例(附demo源码下载)
2016/05/28 Javascript
微信开发 JS-SDK 6.0.2 经常遇到问题总结
2016/12/08 Javascript
js实现tab选项卡切换功能
2017/01/13 Javascript
Vue入门之数据绑定(小结)
2018/01/08 Javascript
layui 监听表格复选框选中值的方法
2018/08/15 Javascript
深入理解Node内建模块和对象
2019/03/12 Javascript
JavaScript迭代器的含义及用法
2019/06/21 Javascript
微信小程序事件流原理解析
2019/11/27 Javascript
微信小程序登录时如何获取input框中的内容
2019/12/04 Javascript
JavaScript事件委托实现原理及优点进行
2020/08/29 Javascript
[19:24]DOTA2客户端使用指南 一分钟快速设置轻松超神
2013/09/24 DOTA
[03:46]显微镜下的DOTA2第七期——满血与残血
2014/06/20 DOTA
Python FTP操作类代码分享
2014/05/13 Python
使用Python下的XSLT API进行web开发的简单教程
2015/04/15 Python
python使用urlparse分析网址中域名的方法
2015/04/15 Python
DataFrame 将某列数据转为数组的方法
2018/04/13 Python
Python实现一个数组除以一个数的例子
2019/07/20 Python
详解pyinstaller selenium python3 chrome打包问题
2019/10/18 Python
Django生成PDF文档显示网页上以及PDF中文显示乱码的解决方法
2019/12/17 Python
PyCharm2020.3.2安装超详细教程
2021/02/08 Python
美国滑雪和滑雪板商店:Buckman
2018/03/03 全球购物
Anya Hindmarch官网:奢侈设计师手袋及配饰
2018/11/15 全球购物
社会实践评语
2014/04/28 职场文书
高校教师个人工作总结2014
2014/12/17 职场文书
2015年校本培训工作总结
2015/07/24 职场文书
深入理解go缓存库freecache的使用
2022/02/15 Golang