Chinaunix首页 | 论坛 | 博客
  • 博客访问: 345205
  • 博文数量: 97
  • 博客积分: 2130
  • 博客等级: 大尉
  • 技术积分: 1800
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-24 11:51
文章分类
文章存档

2013年(57)

2012年(40)

我的朋友

分类: PHP

2013-01-23 09:42:54

 

清单 3. SAX 解析器读取图书 XML

 

 

  ?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";

  }

  ?

 


   脚本首先设置 g_books 数组,它在内存中容纳所有图书和图书信息,g_elem 变量保存脚本目前正在处理的标记的名称。然后脚本定义回调函数。在这个示例中,回调函数是 startElementendElement textData。在打开和关闭标记的时候,分别调用 startElement endElement 函数。在开始和结束标记之间的文本上面,调用 textData

  在这个示例中,startElement 标记查找 book 标记,在 book 数组中开始一个新元素。然后,textData 函数查看当前元素,看它是不是 publishertitle author 标记。如果是,函数就把当前文本放入当前图书。

   为了让解析继续,脚本用 xml_parser_create 函数创建解析器。然后,设置回调句柄。之后,脚本读取文件并把文件的大块内容发送到解析器。在文件读取之后,xml_parser_free 函数删除解析器。脚本的末尾输出 g_books 数组的内容。

  可以看到,这比编写 DOM 的同样功能要困难得多。如果没有 DOM 库也没有 SAX 库该怎么办?还有替代方案么?请看下篇博文,或参考

阅读(1054) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~