文章教程

17.3在PHP中处理XML

9/17/2020 9:31:19 PM 人评论 次浏览

17.3 在PHP中处理XML

虽然PHP在以前的版本中就已经提供了对XML的支持,但是随着PHP5的出现,这种支持大大增强了。由于PHP4对XML的支持比较有限,比如默认情况下只提供基于SAX的解析器、PHP4DOM没有实现W3C标准等。

PHP5包括彻底重新编写的和新增加的扩展,如SAX解析器、DOM、SimpleXML、XMLReader、XMLWriter和XSLT处理程序。所有这些扩展都以libxml2为基础。除了自PHP4改进的SAX支持以外,PHP5还同时支持符合W3C标准的DOM和SimpleXML扩展。默认情况下同时支持SAX、DOM和SimpleXML。如果熟悉其他语言中的DOM,使用PHP实现类似的功能会更简单。

17.3.1 在PHP中建立对XML的支持

通常,在Windows安装PHP5时,对XML的支持就已经建立,读者可以通过使用向页面输出函数phpinfo()的内容查看当前的PHP是否对XML支持,如图17-4、图17-5及图17-6所示。

图17-4 PHP中对XML的DOM支持

图17-5 PHP中的SimpleXML信息

图17-6 PHP中对XML支持的其他相关信息

17.3.2 用PHP函数处理XML文档

Expat是PHP脚本语言的XML解析器,亦称为XML处理器,是一种基于事件的解析器,它提供了一系列函数可以使程序访问XML文档的结构和内容。XML解析器有如下两种基本类型。

·基于树形的解析器:将XML文档转换成树型结构。这类解析器分析整篇文章,同时提供一个API来访问所产生树的每个元素。其通用的标准为DOM,即文档对象模式。

·基于事件的解析器,将XML文档视为一系列的事件。当一个特殊事件发生时,解析器将调用开发者提供的函数来处理。基于事件的解析器有一个XML文档的数据集中视图,也就是说它集中在XML文档的数据部分,而不是其结构。这些解析器从头到尾处理文档,并将类似于元素的开始、元素的结尾、特征数据的开始等事件通过回调(callback)函数报告给应用程序。

这里简单解释一下基于事件的XML解析器,请看下面的XML代码片段。


<title>Learning PHP5</title>

对于基于事件的XML分析器,会将面的XML代码片段分析为如下事件。

·元素开始:title。

·CDATA部分开始,value:Learning PHP5。

·元素结束:title。

本节先为读者介绍这些XML处理函数,即Expat所提供的函数,最后再通过一个具体实例讲解这些函数的具体用法。

从Apache1.3.22开始,Expat已经作为Apache的一部分。在UNIX系统中,可以通过-with-xml选项配置PHP将其编译入PHP。如果将PHP编译为Apache的模块,Expat将默认作为Apache的一部分。在Windows中,则必须要加载XML动态链接库。

17.3.3 XML解析器的建立和释放

函数xml_parser_create()用来初始化一个XML解析器,即建立XML解析器的实例,该实例将用于以后的所有函数。这一点非常类似于PHP中MySQL函数的连接。该函数语法如下。


resource xml_parser_create([string $encoding])

该函数建立一个新的XML解析器,并返回可被其他XML函数使用的资源句柄。该函数有一个可选参数,用来指定要被解析的XML输入的字符编码方式。PHP5开始,可以自动侦测输入的XML编码,因此$encoding参数仅用来指定解析后输出数据的编码。默认输出的字符编码是ISO-8859-1,而PHP5.0.2及以上版本是UTF-8。

函数xml_parser_free()用来释放指定的XML解析器,语法如下。


bool xml_parser_free (resource $parser)

参数$parser是要释放的XML解析器的指针。如果参数$parser没有指向一个合法的解析器,该函数将返回FALSE,否则将释放指定的解析器并返回TRUE。

17.3.4 处理XML元素的函数

函数xml_set_element_handler()用来处理建立起始和终止元素处理器,用法如下。


bool xml_set_element_handler (resource $parser, callback $start_elem_handler, callback         $end_elem_handler )

函数xml_set_element_handler()的第1个参数$parser是指向要调用处理器的XML解析器的指针参数,第2个参数$start_elem_handler和第3个参数$end_elem_handler是表示函数名称的字符串。如果处理器被成功建立,该函数将返回TRUE。如果参数$parser指向的不是合法的解析器,该函数将返回FALSE。

第2个参数$start_elem_handler所指定的函数将在一个元素开始的时候调用,也就是说,当XML分析器遇到元素开始事件时,就会调用参数$start_elem_handler所指定的函数。同理,遇到元素结束事件时,该函数就会调用参数$end_elem_handler所指定的函数。

由参数$start_elem_handler所指定的函数,必须有3个参数,各参数解释如下所述。

·第1个参数parser,是指向要调用XML解析器的指针。

·第2个参数name,为该处理器所调用的元素名。

·第3个参数data,是一个包含有对应元素的属性的数组,数组元素的下标为属性名,元素的值即为属性的值。

类似地,由参数$end_elem_handler所指定的函数必须包含两个参数,各参数解释如下所述。

·第1个参数parser,是指向要调用XML解析器的指针。

·第2个参数name,为该处理器所调用的元素名。

本章第17.5.5小节的实例代码有该函数的具体应用,读者可以仔细研究有关代码,以便准确理解本小节所述内容。

17.3.5 处理XML字符数据的函数

函数xml_set_character_data_handler()用来建立字符数据处理器,用法如下。


bool xml_set_character_data_handler (resource $parser, callback $handler)

该函数是参数$parser指向的XML解析器指定字符数据处理函数。参数$handler是一个表示函数名称的字符串。由参数$handler所指定的函数,将在分析器遇到一个字符数据事件时调用。如果处理器被成功的建立,该函数将返回TRUE。如果参数$parser指向的不是合法的解析器,该函数将返回FALSE。

该函数和函数xml_set_element_handler()极为类似,由参数$handler所指定的函数必须含有两个参数,各参数解释如下所述。

·第1个参数parser,是指向要调用XML解析器的指针。

·第2个参数data,是包含有字符数据的字符串。

17.3.6 解析一个XML文档

函数xml_parse()用来解析一个XML文档,语法如下。


int xml_parse (resource $parser, string $data [, bool $is_final])

函数xml_parse()的第1个参数$parser是一个指向XML解析器的指针,第2个参数是需要解析的数据集。可以多次对新的数据调用xml_parse()函数来分段解析一个文档,这时,只要在解析最后一段数据时将参数$is_final的值设置为TRUE即可。第3个参数,如果被设置为TRUE,则data为当前解析中最后一段数据。

17.3.7 完整实例分析

这小节将通过一个具体实例使读者了解这些函数在PHP程序中的具体用法。使用的XML文档就是在17.2小节创建的17-1.xml。

这节的实例程序将首先在PHP程序中初始化XML分析器,然后为不同的XML事件定义不同的处理器,最后分析XML文档。代码17-2是实例的完整程序,执行结果如图17-7所示。

代码17-2 使用Expat函数处理XML文档17-2.php


     01 <?php
     02 $parser=xml_parser_create();                            //
初始化XML
分析器
     03 
     04 function start($parser,$elem_name,$elem_attrs)          //
在一个元素开始时调用的函数
     05 {
     06     switch($elem_name)
     07     {
     08         case "BOOKS":
     09             echo "<b>-- 
图书信息 --</b><br/><br/>";
     10             break;
     11         case "TITLE":
     12             echo "<b>
书名: </b>";
     13             break;
     14         case "AUTHOR":
     15             echo "<b>
作者: </b>";
     16             break;
     17         case "PUBLISHER":
     18             echo "<b>
出版社: </b>";
     19             break;
     20         case "PRICE":
     21             echo "<b>
价格: </b>";
     22             break;
     23     }
     24 }
     25 
     26 function stop($parser,$elem_name)                       //
在一个元素结束时调用的函数
     27 {
     28     echo "<br />";
     29 }
     30 
     31 function char($parser,$data)                            //
当找到一个字符数据时调用该函数
     32 {
     33     echo $data;
     34 }
     35 
     36 
     37 xml_set_element_handler($parser,"start","stop");        //
指定元素处理器
     38 xml_set_character_data_handler($parser,"char");         //
指定字符数据处理器
     39 
     40 $fp=fopen("17-1.xml","r");                              //
打开XML
文件
     41 while($data=fread($fp,1024))                            //
循环读入XML
文件中的内容
     42 {
     43     xml_parse($parser,$data,feof($fp)) or 
     44     die(sprintf("XML
错误: %s at line %d", 
     45     xml_error_string(xml_get_error_code($parser)),
     46     xml_get_current_line_number($parser)));
     47 }
     48 
     49 xml_parser_free($parser);                               //
释放XML
分析器资源
     50 ?>

图17-7 使用Expat函数处理XML文档的输出结果

【代码解析】下面对代码17-2的各个关键点加以解释。代码第02行使用函数xml_parser_create()初始化一个XML分析器。代码第04行建立函数star()用来当XML分析器找到一个元素开始时调用,这个函数内部通过判断作为参数传入的元素名称,来显示不同的文字。注意,判断元素名称时,元素名称用大写字母,无论XML文档中使用的是否是大写或小写字母。代码第26行定义函数stop()在一个元素结束时调用,该函数仅仅用来向页面输出换行。代码第31行定义函数char()在XML分析器找到一个字符数据是调用,该函数向页面输出这个字符数据。

接下来的代码就是实际的PHP处理XML函数。代码第37行使用函数xml_set_element_handler()指定元素处理器,其第2个参数就是代码第4行定义函数的名称start,以字符串形式传入函数xml_set_element_handler();第3个参数就是第26行定义的函数名称stop,同样是以字符串形式将函数名称“stop”传入函数xml_set_element_handler()。这样,当函数xml_set_element_handler()在处理XML元素开始和结束部分的时候就会分别调用程序自定义的函数start()和stop()。

代码第38行使用函数xml_set_character_data_handler()指定字符数据的XML处理器。同理,该函数也使用了自定义函数char()的名称“char”作为其第2个参数,这样当分析到一个XML字符数据时,就会调用函数char()来输出该字符数据。

代码第40行使用函数fopen()打开XML文件17-1.xml,接着在第43行调用函数xml_parse()分析读入的XML数据。同时,在分析XML出现错误时调用函数xml_error_string()和xml_get_current_line_number()分别获取错误信息和错误所在行。代码最后使用函数xml_parser_free()释放程序开始建立的XML分析器实例。

教程类别