建站学 - 轻松建站从此开始!

建站学-个人建站指南,网页制作,网站设计,网站制作教程

当前位置: 建站学 > 网站开发 > PHP教程 >

用PHP读取和编写XML及DOM(2)

时间:2010-09-16 00:48来源: 作者: 点击:
使用DOM库读取XML 读取格式良好的 XML 文件最容易的方式是使用编译成某些 PHP 安装的文档对象模型 (DOM)库。DOM 库把整个 XML 文档读入内存,并用节点树表示它,如图 1 所示。 树顶部的 books 节点有两个 book 子
 

 

使用DOM库读取XML

读取格式良好的 XML 文件最容易的方式是使用编译成某些 PHP 安装的文档对象模型 (DOM)库。DOM 库把整个 XML 文档读入内存,并用节点树表示它,如图 1 所示。

树顶部的 books 节点有两个 book 子标记。在每本书中,有 author、publisher 和 title 几个节点。author、publisher 和 title 节点分别有包含文本的文本子节点。读取图书 XML 文件并用 DOM 显示内容的代码如清单 2 所示。

清单 2. 用DOM读取图书XML

  1. <?php 
  2. $doc = new DOMDocument();  
  3. $doc->load( 'books.xml' );  
  4.  
  5. $books = $doc->getElementsByTagName( "book" );  
  6. foreach( $books as $book )  
  7. {  
  8. $authors = $book->getElementsByTagName( "author" );  
  9. $author = $authors->item(0)->nodeValue;  
  10.  
  11. $publishers = $book->getElementsByTagName( "publisher" );  
  12. $publisher = $publishers->item(0)->nodeValue;  
  13.  
  14. $titles = $book->getElementsByTagName( "title" );  
  15. $title = $titles->item(0)->nodeValue;  
  16.  
  17. echo "$title - $author - $publisher\n";  
  18. }  
  19. ?> 

脚本首先创建一个new DOMdocument对象,用load方法把图书 XML 装入这个对象。之后,脚本用 getElementsByName 方法得到指定名称下的所有元素的列表。在 book 节点的循环中,脚本用getElementsByName方法获得author、publisher和 title 标记的 nodeValue。nodeValue 是节点中的文本。脚本然后显示这些值。可以在命令行上像这样运行 PHP 脚本:

  1. % php e1.php   
  2. PHP Hacks - lvtao.net for php100
  3. Podcasting Hacks - lvtao.net for php100 
  4. %  

可以看到,每个图书块输出一行。这是一个良好的开始。但是,如果不能访问 XML DOM 库该怎么办?

用SAX解析器读取XML

读取 XML 的另一种方法是使用 XML Simple API(SAX)解析器。PHP 的大多数安装都包含 SAX 解析器。SAX 解析器运行在回调模型上。每次打开或关闭一个标记时,或者每次解析器看到文本时,就用节点或文本的信息回调用户定义的函数。

SAX 解析器的优点是,它是真正轻量级的。解析器不会在内存中长期保持内容,所以可以用于非常巨大的文件。缺点是编写 SAX 解析器回调是件非常麻烦的事。清单 3 显示了使用 SAX 读取图书 XML 文件并显示内容的代码。

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

  1. <?php 
  2. $g_books = array();  
  3. $g_elem = null;  
  4.  
  5. function startElement( $parser, $name, $attrs )   
  6. {  
  7. global $g_books, $g_elem;  
  8. if ( $name == 'BOOK' ) $g_books []= array();  
  9. $g_elem = $name;  
  10. }  
  11.  
  12. function endElement( $parser, $name )   
  13. {  
  14. global $g_elem;  
  15. $g_elem = null;  
  16. }  
  17.  
  18. function textData( $parser, $text )  
  19. {  
  20. global $g_books, $g_elem;  
  21. if ( $g_elem == 'AUTHOR' ||  
  22. $g_elem == 'PUBLISHER' ||  
  23. $g_elem == 'TITLE' )  
  24. {  
  25. $g_books[ count( $g_books ) - 1 ][ $g_elem ] = $text;  
  26. }  
  27. }  
  28.  
  29. $parser = xml_parser_create();  
  30.  
  31. xml_set_element_handler( $parser, "startElement", "endElement" );  
  32. xml_set_character_data_handler( $parser, "textData" );  
  33.  
  34. $f = fopen( 'books.xml', 'r' );  
  35.  
  36. while( $data = fread( $f, 4096 ) )  
  37. {  
  38. xml_parse( $parser, $data );  
  39. }  
  40.  
  41. xml_parser_free( $parser );  
  42.  
  43. foreach( $g_books as $book )  
  44. {  
  45. echo $book['TITLE']." - ".$book['AUTHOR']." - ";  
  46. echo $book['PUBLISHER']."\n";  
  47. }  
  48. ?> 

脚本首先设置 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 库该怎么办?还有替代方案么?

(责任编辑:admin)
织梦二维码生成器
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片