代码如下:
- <?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已忽略了).
|