PHP - SAX 解析器示例



PHP 在 php.ini 设置文件中默认启用了 XML 解析器扩展。此解析器实现 SAX API,这是一种基于事件的解析算法。

基于事件的解析器不会将整个 XML 文档加载到内存中。相反,它一次读取一个节点。解析器允许您实时交互。一旦您移至下一个节点,旧节点就会从内存中移除。

基于 SAX 的解析机制比基于树的解析器更快。PHP 库包含处理 XML 事件的函数,如本章所述。

解析 XML 文档的第一步是使用 xml_parse_create() 函数创建一个解析器对象。

xml_parser_create(?string $encoding = null): XMLParser

此函数创建一个新的 XML 解析器并返回一个 XMLParser 对象,供其他 XML 函数使用。

xml_parse() 函数开始解析 XML 文档。

xml_parse(XMLParser $parser, string $data, bool $is_final = false): int

xml_parse() 解析 XML 文档。配置事件的处理程序会根据需要调用多次。

XMLParser 扩展提供了不同的事件处理程序函数。

xml_set_element_handler()

此函数为 XML 解析器设置元素处理程序函数。每当 XML 解析器遇到开始或结束标记时,都会发出元素事件。开始标记和结束标记有单独的处理程序。

xml_set_element_handler(XMLParser $parser, callable $start_handler, 
   callable $end_handler): true

当打开新的 XML 元素时,会调用 start_handler() 函数。当关闭 XML 元素时,会调用 end_handler() 函数。

xml_set_character_data_handler()

此函数为 XML 解析器设置字符数据处理程序函数。字符数据大致是 XML 文档的所有非标记内容,包括标记之间的空白字符。

xml_set_character_data_handler(XMLParser $parser, callable $handler): true

xml_set_processing_instruction_handler()

此函数为 XML 解析器设置处理指令 (PI) 处理程序函数。<?php ?> 是一个处理指令,其中 php 被称为“PI 目标”。这些的处理是特定于应用程序的。

xml_set_processing_instruction_handler(XMLParser $parser, callable $handler): true

一个处理指令具有以下格式:

<?target
   data
?>

xml_set_default_handler()

此函数为 XML 解析器设置默认处理程序函数。不属于其他处理程序的内容将转到默认处理程序。您将在默认处理程序中获得 XML 和文档类型声明等内容。

xml_set_default_handler(XMLParser $parser, callable $handler): true

示例

以下示例演示了如何使用 SAX API 解析 XML 文档。我们将使用 SAX.xml 如下所示:

<?xml version = "1.0" encoding = "utf-8"?>
<tutors>
   <course>
      <name>Android</name>
      <country>India</country>
      <email>[email protected]</email>
      <phone>123456789</phone>
   </course>

   <course>
      <name>Java</name>
      <country>India</country>
      <email>[email protected]</email>
      <phone>123456789</phone>
   </course>

   <course>
      <name>HTML</name>
      <country>India</country>
      <email>[email protected]</email>
      <phone>123456789</phone>
   </course>
</tutors>

示例

解析上述文档的 PHP 代码如下所示。它打开 XML 文件并调用 xml_parse() 函数,直到到达其文件末尾。事件处理程序将数据存储在 tutors 数组中。然后按元素逐个输出数组。

<?php

   // Reading XML using the SAX(Simple API for XML) parser 
   $tutors   = array();
   $elements   = null;

   // Called to this function when tags are opened 
   function startElements($parser, $name, $attrs) {
      global $tutors, $elements;
      if(!empty($name)) {
         if ($name == 'COURSE') {
		 
            // creating an array to store information
            $tutors []= array();
         }
         $elements = $name;
      }
   }

   // Called to this function when tags are closed 
   function endElements($parser, $name) {
      global $elements;

      if(!empty($name)) {
         $elements = null;
      }
   }

   // Called on the text between the start and end of the tags
   function characterData($parser, $data) {
      global $tutors, $elements;
      if(!empty($data)) {
         if ($elements == 'NAME' || $elements == 'COUNTRY' ||  $elements == 'EMAIL' ||  $elements == 'PHONE') {
            $tutors[count($tutors)-1][$elements] = trim($data);
         }
      }
   }

   $parser = xml_parser_create();
   xml_set_element_handler($parser, "startElements", "endElements");
   xml_set_character_data_handler($parser, "characterData");

   // open xml file
   if (!($handle = fopen('sax.xml', "r"))) {
      die("could not open XML input");
   }

   while($data = fread($handle, 4096)) {
      xml_parse($parser, $data);  
   }

   xml_parser_free($parser); 
   $i = 1;

   foreach($tutors as $course) {
      echo "course No - ".$i. '<br/>';
      echo "course Name - ".$course['NAME'].'<br/>';
      echo "Country - ".$course['COUNTRY'].'<br/>';
      echo "Email - ".$course['EMAIL'].'<br/>';
      echo "Phone - ".$course['PHONE'].'<hr/>'; 
      $i++; 
   }
?>

以上代码给出以下输出:

course No - 1
course Name - Android
Country - India
Email - [email protected]
Phone - 123456789
________________________________________
course No - 2
course Name - Java
Country - India
Email - [email protected]
Phone - 123456789
________________________________________
course No - 3
course Name - HTML
Country - India
Email - [email protected]
Phone - 123456789
________________________________________
广告