PHP进行XML编程.docx
- 文档编号:24313798
- 上传时间:2023-05-26
- 格式:DOCX
- 页数:33
- 大小:60.96KB
PHP进行XML编程.docx
《PHP进行XML编程.docx》由会员分享,可在线阅读,更多相关《PHP进行XML编程.docx(33页珍藏版)》请在冰豆网上搜索。
PHP进行XML编程
XML(eXtensibleMarkupLanguage,可扩展标识语言),是一种标准化的数据格式。
它看起来有点类似HTML,也有标签(
但和HTML不一样的是,XML设计的目的是为了便于被解析,并且在XML文档中你要遵循很多规则(哪些是你可以做的,哪些是你不能做的)。
现在,在出版、工程、医药等很多领域,XML已经成为一种标准化的数据格式。
XML可用于远程过程调用(RPC,RemoteProcedureCalls)、数据库、商品订单等等。
在很多情况下你可能会用到XML。
因为它是一种数据传送的通用格式,其他程序可以通过提取信息(解析)或者用HTML显示(转换)的方式让你使用XML文件。
本章介绍如何使用PHP内置的XML解析器,也介绍了如何使用可选的XSLT扩展来转换XML。
我们还会简要介绍如何生成XML文档。
最近,XML已经被用于远程过程调用(XML-RPC)。
客户端将函数名和参数值用XML编码后通过HTTP发送至服务器,服务器收到后解码函数名和值,再决定如何处理,最后返回一个XML编码的响应值。
XML-RPC已经被证明是一种集成用不同语言编写的应用程序组件的好方法。
在本章中,我们将会介绍如何编写XML-RPC服务器和客户端。
11.1 入门指南
LightningGuidetoXMLXML
大多数XML文档由元素(类似于HTML标签)、实体和规则数据组成。
例如:
在HTML中,常常可以用不封闭的标签,最常见的例子:
但在XML中,这样是非法的。
XML要求每个开始标签都必须有一个对应的结束标签。
对于没有包含任何事物的标签,例如表示断行的
,XML使用如下语法:
标签可以嵌套但不能重叠,例如这样是合法的:
但这样是非法的,因为book和title标签重叠了:
XML也要求文档以处理指令开始中,以确定所使用的XML版本(或其他内容,如编码)。
例如:
xmlversion="1.0"?
>
对于具有良好格式的XML文档,最重要的是文件顶级层次中只能有一个元素,如下面的格式是良好的:
xmlversion="1.0"?
>
下面的格式则是糟糕的,因为有三个元素在最顶级层次并列存在:
xmlversion="1.0"?
>
XML文档通常不是完全与众不同。
XML文档中特定的标签、属性和实体,还有支配它们如何嵌套的规则构成了文档结构,有两种方法可用于记录这种结构:
DTD(DocumentTypeDefinition,文档类型定义)和Schema。
DTD和Schema用来验证文档,也就是为了保证XML文档遵循其文档类型的规则。
大多数XML文档不包含DTD。
许多XML文档用一个给定DTD的名称和位置(文件或URL)的标签将DTD指定为外部文档:
DOCTYPErssPUBLIC'MyDTDIdentifier''
有时将一个XML封装到另一个XML是很方便的。
例如一个显示邮件信息的XML可能会有一个带有附件的attachment元素。
如果附件文件也是一个XML文档,就形成了一个
嵌套XML文档。
如果邮件信息文件中有一个body元素(邮件主体),并且所带的文件也是XML格式,且也含有一个body元素,但是该元素与前者有着完全不同的DTD规则,那怎么办呢?
如何使body在文件的各部分含义不同但又是合法的?
这个问题可以用命名空间(或称名字空间,namespace)。
命名空间可让你限定XML标签,如:
email:
body和human:
body。
XML还有很多内容我们无法在此介绍,想更详细了解XML,可以阅读ErikRay所著的《LearningXML》(由O'Reilly出版)。
如果需要一本XML语法和标准的完全参考,可以阅读ElliotteRustyHarold和W.ScottMeans所著的《XMLinaNutshell》(由O'Reilly出版)。
11.2 生成XML
GeneratingXML
PHP可以生成(创建)动态HTML,也可以生成动态XML。
你可以为其他程序生成基于表单、数据库查询的XML,也可以为PHP中可以做的任何事生成XML。
动态XML的一个典型应用是RSS(丰富站点摘要,RichSiteSummary,另一种解释为真正简易聚合,ReallySimpleSyndication),一种用来同步新闻站点的文件格式。
你可以读取数据库或者HTML文件中的文章信息,生成一个基于这些信息的XML摘要文件。
用PHP生成XML文档很简单。
只需要用header()函数把文档的MIME类型改成"text/xml"。
为了避免
xml...?
>声明被解释为一个PHP标签,你也需要编辑php.ini,将short_open_tag选项设为不启用,或者直接用echo把这一行打印出来:
php
echo'
xmlversion="1.0"encoding="ISO-8859-1"?
>';
?
>
示例11-1用PHP生成一个RSS文档。
RSS文件是一个包含有若干个channel元素的XML文档,每个channel包含有几个item元素,每个item元素又包含有一个title、一个description和一个link元素。
实际上RSS所支持的属性比示例11-1中所展示的要多。
就像PHP生成HTML没用到什么特殊函数一样,用PHP生成XML也只需要用echo打印内容即可。
示例11-1:
生成一个XML文档
phpheader('Content-Type:
text/xml');?
>
xmlversion='1.0'encoding='ISO-8859-1'?
>
DOCTYPErssPUBLIC'-//NetscapeCommunications//DTDRSS0.91//EN'
'
php
//newsitemstoproduceRSSfor
$items=array(
array('title'=>'ManBitesDog',
'link' =>'
'desc' =>'Ironicturnaround!
'),
array('title'=>'MedicalBreakthrough!
',
'link' =>'
'desc' =>'Doctorsannouncedacureforme.')
);
foreach($itemsas$item){
echo"
echo"
echo" {$item[link]}\n";
echo"
echo"
echo"\n";
}
?
>
xmlversion='1.0'encoding='ISO-8859-1'?
>
DOCTYPErssPUBLIC'-//NetscapeCommunications//DTDRSS0.91//EN'
'
11.3 解析XML
ParsingXML
假设有一些用XML写成的书,你想要建立一个书籍标题和作者的索引。
你需要解析XML文件,识别出title元素和author元素及它们的内容。
你可以用正则表达式和字符串函数(如strtok())完成这个工作,但是有点复杂。
最简单快捷的方法是使用PHP自带的XML解析器。
PHP有3个XML解析器——一个基于ExpatC库的事件驱动型解析器;一个基于DOM的解析器和一个适合于解析简单XML文件的解析器,即SimpleXML。
最常用的解析器是基于事件的,可以在解析时不要求验证XML文档。
也就是说你可以找出当前的XML标签及其包含的内容,但是却不能确定它们是否为正确文档结构中的正确标签。
不过在实际中,通常这不是个大问题。
PHP的XML解析器是事件基于事件的,这意味着当解析器阅读文档时,它将针对各种事件调用不同的处理程序函数,如一个元素的开始和结束。
下面几节我们将讨论你可以提供的处理程序(handler),以及设置这些handler的函数和触发调用handler的事件。
我们也提供了一个样本函数,用来在内存中生成XML文档图,该函数带有一个示例程序,可以很漂亮地输出XML。
11.3.1 元素处理器(ElementHandler)
ElementHandlers
当解析器遇到一个元素的开始标签或结束标签,它会调用起始或结束元素处理器(处理器即一个处理程序)。
我们可通过xml_set_element_handler()函数来设置该处理器:
xml_set_element_handler(parser,start_element,end_element);
start_element和end_element这两个参数是处理器函数的名称。
当XML解析器遇到元素的起始标签时,调用起始元素处理器。
my_start_element_handler(parser,element,attributes);
它传递三个参数:
调用处理程序的XML解析器的引用、起始元素的名称和解析器遇到的元素的属性数组。
考虑到速度,该属性数组也是按引用传递的。
示例11-2包含了起始元素处理器的代码,该处理程序只是简单地将元素名加粗输出,将属性用灰色输出。
示例11-2:
起始元素处理程序
functionstart_element($inParser,$inName,&$inAttributes){
$attributes=array( );
foreach($inAttributesas$key){
$value=$inAttributes[$key];
$attributes[]="
}
echo'<'.$inName.''.join('',$attributes).'>';
}
当解析器到达元素结束标签时,就会调用结束元素处理器:
my_end_element_handler(parser,element);
它有两个参数:
一个调用处理程序的XML解析器的引用和将结束的元素的名称。
示例11-3显示了一个格式化该元素的结束处理器:
示例11-3:
结束元素处理器
functionend_element($inParser,$inName){
echo'</$inName>';
}
11.3.2 字符数据处理器(CharacterDataHandler)
CharacterDataHandler
元素之间的所有文本(如字符数据、XML术语中的CDATA)由字符数据处理程序处理。
通过xml_set_character_data_handler()函数设置的处理器会在遇到每一个字符数据块时被调用。
xml_set_character_data_handler(parser,handler);
字符数据处理器有两个参数:
触发处理程序的XML解析器的引用、包含字符数据的字符串:
my_character_data_handler(parser,cdata);
示例11-4显示了一个简单的输出数据的字符数据处理器:
示例11-4:
字符数据处理器
functioncharacter_data($inParser,$inData){
echo$inData;
}
11.3.3 处理指令
ProcessingInstructions
在XML中处理指令(PI,ProcessingInstruction)用来将脚本或其他代码嵌入到文档中,PHP代码本身就可被看成是一种遵循XML格式的处理指令,它以
php…?
>标签风格标记代码。
XML解析器在遇到处理指令时即调用相应的处理指令处理器。
可以用xml_set_processing_instruction_handler()函数设置处理器:
xml_set_processing_instruction_handler(parser,handler);
处理指令的格式如下:
targetinstructions?
>
处理指令处理器(processinginstructionhandler)有3个参数:
触发处理器的解析器的引用、目标名称(如“php”)和处理指令。
my_processing_instruction_handler(parser,target,instructions);
对处理指令做什么由你决定。
一个技巧就是将PHP代码嵌入到XML文档中。
当解析文档时,用eval()函数执行PHP代码。
示例11-5就是这样做的。
当然你必须依赖正在处理的包含eval()的文档,因为eval()函数将运用所包含的任何代码――即使该代码会删除文件或者把密码发送给黑客。
示例11-5:
处理指令处理器
functionprocessing_instruction($inParser,$inTarget,$inCode){
if($inTarget==='php'){
eval($inCode);
}
}
11.3.4 实体处理器
EntityHandlers
XML中的实体是占位符(placeholder)。
XML提供了5种标准实体(&,>,<,"和'),并且XML文档还可以定义它们自己的实体。
大多数实体定义不会触发事件,在调用其他处理器前,XML解析器会对文档中的大多数实体进行扩展。
PHP的XML库对外部实体(externalentity)和未解析实体(unparsedentity)提供特别支持。
外部实体的替换文本(replacementtext)是由文件名或者URL表示的,而不是在XML文件中显式地给定的。
你可以定义一个处理器,并在字符数据中出现外部实体时调用。
但是否解析该文件或URL的内容,则由用户自身决定。
未解析实体必须带有一个符号声明。
你可以定义未解析实体和符号声明,则未解析实体将在调用字符数据处理器前被删除。
11.3.4.1 外部实体
外部实体允许XML文档包含其他XML文档。
一个外部实体引用的处理器打开被引用的文件,然后解析该文件并且将结果包含在当前文档中。
可用xml_set_external_entity_ref_handler()函数来设置处理器,该函数有两个参数:
XML解析器的引用和处理器函数的名称:
xml_set_external_entity_ref_handler(parser,handler);
外部实体处理器有5个参数:
触发处理器的XML解析器、实体名称、分解实体标识符的基本URL(当前为空)、系统标识符(如文件名)和实体的公共标识符,实体声明如下:
$ok=my_ext_entity_handler(parser,entity,base,system,public);
如果外部实体处理器返回一个false值(或没有返回任何值),XML解析器将停止并报告一个XML_ERROR_EXTERNAL_ENTITY_HANDLING错误。
如果返回true,则解析继续。
示例11-6介绍了如何解析外部引用的XML文档。
我们定义了两个函数create_parser()和parse(),来创建XML解析器和进行解析工作。
你可以用它们来解析顶层文档和由外部引用包含的任何文档。
这样的函数将在后面的“使用解析器”一节中详细介绍。
外部实体引用处理器只是简单地确定哪些文件要传递给这些函数。
示例11-6:
外部实体引用处理器
functionexternal_entity_reference($inParser,$inNames,$inBase,
$inSystemID,$inPublicID){
if($inSystemID){
if(!
list($parser,$fp)=create_parser($inSystemID)){
echo"Erroropeningexternalentity$inSystemID\n";
returnfalse;
}
returnparse($parser,$fp);
}
returnfalse;
}
11.3.4.2 未解析实体
未解析实体的声明要带有一个符号声明:
DOCTYPEdoc[
NOTATIONjpegSYSTEM"image/jpeg">
ENTITYlogoSYSTEM"php-tiny.jpg"NDATAjpeg>
]>
使用xml_set_notation_decl_handler()函数可注册一个符号声明处理器:
xml_set_notation_decl_handler(parser,handler);
调用处理器时要带有5个参数:
my_notation_handler(parser,notation,base,system,public);
Base参数是分解符号标识符的基本URL,可以设置system标识符或public标识符,但是不能两者同时设置。
使用xml_set_unparsed_entity_decl_handler()函数可以注册一个未解析实体声明处理器:
xml_set_unparsed_entity_decl_handler(parser,handler);
这个处理器被调用时带有6个参数:
my_unp_entity_handler(parser,entity,base,system,public,notation);
notation参数确定该未解析实体关联的符号声明。
11.3.5 默认处理器
DefaultHandler
对任何其他事件,如XML声明和XML文档类型,将调用默认处理器(DefaultHandler)。
可调用xml_set_default_handler()函数来设置默认器:
xml_set_default_handler(parser,handler);
该处理器有两个参数:
my_default_handler(parser,text);
Text参数根据触发默认处理器的事件种类不同而具有不同的值。
示例11-7仅输出调用默认处理程序时的给定字符串。
示例11-7:
Defaulthandler
functiondefault($inParser,$inData){
echo"
Defaulthandlercalledwith'$inData'\n";
}
11.3.6 选项
Options
XML解析器有几个选项可用来控制源文档编码、目标文档编码和大小写形式。
使用xml_parser_set_option()可以设置这些选项:
xml_parser_set_option(parser,option,value);
类似地,使用xml_parser_get_option()可得到XML解析器的选项设置信息:
$value=xml_parser_get_option(parser,o
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- PHP 进行 XML 编程