选择显示字体大小

用php读取和编写xml dom (2)

     用 sax 解析器读取 xml
  
    读取 xml 的另一种方法是使用 xml simple api(sax)解析器。php 的大多数安装都包含 sax 解析器。sax 解析器运行在回调模型上。每次打开或关闭一个标记时,或者每次解析器看到文本时,就用节点或文本的信息回调用户定义的函数。
  
    sax 解析器的优点是,它是真正轻量级的。解析器不会在内存中长期保持内容,所以可以用于非常巨大的文件。缺点是编写 sax 解析器回调是件非常麻烦的事。清单 3 显示了使用 sax 读取图书 xml 文件并显示内容的代码。
  
    清单 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 变量保存脚本目前正在处理的标记的名称。然后脚本定义回调函数。在这个示例中,回调函数是 startelement、endelement 和 textdata。在打开和关闭标记的时候,分别调用 startelement 和 endelement 函数。在开始和结束标记之间的文本上面,调用 textdata。
  
    在这个示例中,startelement 标记查找 book 标记,在 book 数组中开始一个新元素。然后,textdata 函数查看当前元素,看它是不是 publisher、title 或 author 标记。如果是,函数就把当前文本放入当前图书。
  
    为了让解析继续,脚本用 xml_parser_create 函数创建解析器。然后,设置回调句柄。之后,脚本读取文件并把文件的大块内容发送到解析器。在文件读取之后,xml_parser_free 函数删除解析器。脚本的末尾输出 g_books 数组的内容。
  
    可以看到,这比编写 dom 的同样功能要困难得多。如果没有 dom 库也没有 sax 库该怎么办?还有替代方案么?
  
    用正则表达式解析 xml
  
    可以肯定,即使提到这个方法,有些工程师也会批评我,但是确实可以用正则表达式解析 xml。清单 4 显示了使用 preg_ 函数读取图书文件的示例。
  
    清单 4. 用正则表达式读取 xml
  
   <?php
   $xml = "";
   $f = fopen( 'books.xml', 'r' );
   while( $data = fread( $f, 4096 ) ) { $xml .= $data; }
   fclose( $f );
  
   preg_match_all( "/\<book\>(.*?)\<\/book\>/s",
   $xml, $bookblocks );
  
   foreach( $bookblocks[1] as $block )
   {
   preg_match_all( "/\<author\>(.*?)\<\/author\>/",
   $block, $author );
   preg_match_all( "/\<title\>(.*?)\<\/title\>/",
   $block, $title );
   preg_match_all( "/\<publisher\>(.*?)\<\/publisher\>/",
   $block, $publisher );
   echo( $title[1][0]." - ".$author[1][0]." - ".
   $publisher[1][0]."\n" );
   }
   ?>
  
  
  
    请注意这个代码有多短。开始时,它把文件读进一个大的字符串。然后用一个 regex 函数读取每个图书项目。最后用 foreach 循环,在每个图书块间循环,并提取出 author、title 和 publisher。
  
    那么,缺陷在哪呢?使用正则表达式代码读取 xml 的问题是,它并没先进行检查,确保 xml 的格式良好。这意味着在读取之前,无法知道 xml 是否格式良好。而且,有些格式正确的 xml 可能与正则表达式不匹配,所以日后必须修改它们。
  
    我从不建议使用正则表达式读取 xml,但是有时它是兼容性最好的方式,因为正则表达式函数总是可用的。不要用正则表达式读取直接来自用户的 xml,因为无法控制这类 xml 的格式或结构。应当一直用 dom 库或 sax 解析器读取来自用户的 xml
  
  
    


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons