Heim > php教程 > php手册 > XML在PHP中应用

XML在PHP中应用

WBOY
Freigeben: 2016-06-13 10:38:44
Original
837 Leute haben es durchsucht

 综述
  XML代表Extensible Markup Language(eXtensible Markup Language的缩写,意为可扩展的标记语言)。XML是一套定义语义标记的规则,这些标记将文档分成许多部件并对这些部件加以标识。它也是元标记语言,即定义了用于定义其他与特定领域有关的、语义的、结构化的标记语言的句法语言。XML是当今最热门的技术。而PHP也具有分析XML文档的功能,下面我们将共同探讨一下PHP中的XML应用的情况。

  XML概貌
  谈起XML(eXtended Markup Language:可扩展标记语言),我们不妨先看一段HTML的代码:
  <html>
  <title>XML</title>
  <body>
  <p><center><font color="red">TEXT</font></center></p>
  <a href="www.domain.com"><img src="logo.jpg"/></a>
  </body>
  </html>
  上面这段代码从结构上就符合XML的规则,XML可以理解是包含数据的树形的结构类型:
  1、引用同一个元素的时候,使用一致的大小写,如<center></Center>就是不符合规定的
  2、任何属性值(如 href="????")要用""引起来,如<a href=www.yahoo.com>就是不正确的
  3、所有元素必须由打开<和关闭>标注组成,元素应该形如<body></body>或空元素<img ... />,如果结尾的 "/>" 少了"/"就是错误的代码
  4、所有元素必须彼此嵌套,就像写程序的循环一样,而且,所有的元素必须嵌套于根元素之中,比如上面的代码所有的内容都嵌套于<html></html>之中。
  5、元素名称(即上面的body a p img等)应为字母开头。

  怎样应用PHP的XML解析器 Expat?
  Expat是PHP脚本语言的XML解析器(同样称为XML处理器),可以使程序访问XML文档的结构和内容。它是一种基于事件的解析器。XML解析器有两种基本类型:
  基于树型的解析器:将XML文档转换成树型结构。这类解析器分析整篇文章,同时提供一个API来访问所产生树的每个元素。其通用的标准为DOM(文档对象模式)。
  基于事件的解析器:将XML文档视为一系列的事件。当一个特殊事件发生时,解析器将调用开发者提供的函数来处理。基于事件的解析器有一个XML文档的数据集中视图,也就是说它集中在XML文档的数据部分,而不是其结构。这些解析器从头到尾处理文档,并将类似于-元素的开始、元素的结尾、特征数据的开始等等-事件通过回调(callback)函数报告给应用程序。
  以下是一个"Hello-World"的XML文档范例:
<greeting>
Hello World
</greeting>
  基于事件的解析器将报告为三个事件:
  开始元素:greeting
  CDATA项的开始,值为:Hello World
  结束元素:greeting
  基于事件的解析器不产生描述文档的结构,当然如果使用Expat,必要时它一样可以在PHP中生成完全的原生树结构。在CDATA项中,基于事件的解析器不会得到父元素greeting的信息。然而,它提供一个更底层的访问,这就使得可以更好地利用资源和更快地访问。通过这种方式,就没有必要将整个文档放入内存;而事实上,整个文档甚至可以大于实际内存值。

  上面Hello-World的范例虽然包括完整的XML格式,但它是无效的,因为既没有DTD(文档类型定义)与其联系,也没有内嵌DTD。但是 Expat是一个不检查有效性的解析器,因此忽略任何与文档联系的DTD。应注意的是文档仍然需要完整的格式,否则Expat(和其他符合XML标准的解析器一样)将会随着出错信息而停止。

  编译Expat
  Expat可以编译进PHP3.0.6版本(或以上)中。从Apache1.3.22开始,Expat已经作为Apache的一部分。在Unix系统中,可以通过-with-xml选项配置 PHP将其编译入PHP。
  如果将PHP编译为Apache的模块,而Expat将默认作为Apache的一部分。在Windows 中,则必须要加载XML动态连接库。
  XML范例:XMLstats
  我们所要讨论的范例是使用Expat来收集XML 文档的统计数据。
  对于文档中每个元素,以下信息都将被输出:
    * 该元素在文档中使用的次数
    * 该元素中字符数据的数量
    * 元素的父元素
    * 元素的子元素
  注意:为了演示,我们利用PHP来产生一个结构来保存元素的父元素和子元素

  用于产生XML解析器实例的函数有哪些?
  用于产生XML解析器实例的函数为xml_parser_create()。该实例将用于以后的所有函数。这个思路非常类似于PHP中MySQL函数的连接标记。在解析文档前,基于事件的解析器通常要求注册回调函数-用于特定的事件发生时调用。Expat没有例外事件,它定义了如下七个可能事件:

对象              XML解析函数                 描述
元素             xml_set_element_handler()                元素的开始和结束
字符数据         xml_set_character_data_handler()          字符数据的开始
外部实体         xml_set_external_entity_ref_handler()     外部实体出现
未解析外部实体   xml_set_unparsed_entity_decl_handler()    未解析的外部实体出现
处理指令         xml_set_processing_instruction_handler()  处理指令的出现
记法声明         xml_set_notation_decl_handler()            记法声明的出现
默认             xml_set_default_handler()                  其它没有指定处理函数的事件

  所有的回调函数必须将解析器的实例作为其第一个参数(此外还有其它参数)。
  对于本文最后的范例脚本,需要注意的是它既用到了元素处理函数又用到了字符数据处理函数。元素的回调处理函数通过xml_set_element_handler()来注册。
  这个函数需要三个参数:
  解析器的实例
  处理开始元素的回调函数的名称
  处理结束元素的回调函数的名称
  当开始解析XML文档时,回调函数必须存在。它们必须定义为与PHP手册中所描述的原型一致。
  例如,Expat将三个参数传递给开始元素的处理函数。在脚本范例中,其定义如下:
  function start_element($parser, $name, $attrs)
  $parser是解析器标志,$name是开始元素的名称,$attrs为包含元素所有属性和值的数组。
  一旦开始解析XML文档,Expat在遇到开始元素是都将调用start_element()函数并将参数传递过去。

  XML 的Case Folding选项
  用xml_parser_set_option()函数将Case folding选项关闭。这个选项默认是打开的,使得传递给处理函数的元素名自动转换为大写。但XML对大小写是敏感的(所以大小写对统计XML文档是非常重要的)。对于我们的范例,case folding选项必须关闭。

  如何对文档进行解析?
  在完成所有的准备工作后,现在脚本终于可以解析XML文档:
  Xml_parse_from_file(),一个自定义的函数,打开参数中指定的文件,并以4kb的大小进行解析
xml_parse(),和xml_parse_from_file()一样,当发生错误时,即XML文档的格式不完全时,将会返回 false。
  我们可以使用xml_get_error_code()函数来得到最后一个错误的数字代码。将此数字代码传递给 xml_error_string()函数即可得到错误的文本信息。输出XML当前的行数,使得调试更容易。
  当解析文档时,对于 Expat需要强调问题的是:如何保持文档结构的基本描述?
  如前所述,基于事件的解析器本身并不产生任何结构信息。不过标签 (tag)结构是XML的重要特性。例如,元素序列<book><title>表示的意思不同于<figure><title>。书名和图名是没有关系的,虽然它们都用到"title"这个术语。因此,为了更有效地使用基于事件的解析器处理XML,必须使用自己的栈(stacks)或列表(lists) 来维护文档的结构信息。
  为了产生文档结构的镜像,脚本至少需要知道目前元素的父元素。用Exapt的API是无法实现的,它只报告目前元素的事件,而没有任何前后关系的信息。因此,需要建立自己的栈结构。
  脚本范例使用先进后出(FILO)的栈结构。通过一个数组,栈将保存全部的开始元素。对于开始元素处理函数,目前的元素将被array_push()函数推到栈的顶部。相应的,结束元素处理函数通过 array_pop()将最顶的元素移走。
  对于序列<book><title></title></book>,栈的填充如下:
  开始元素book:将"book"赋给栈的第一个元素($stack[0])。
  开始元素title:将"title"赋给栈的顶部 ($stack[1])。
  结束元素title:从栈中将最顶部的元素移去($stack[1])。
  结束元素title:从栈中将最

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Empfehlungen
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage