PHP - SAX Parser 示例
PHP 在 php.ini 配置文件中默认启用了 XML parser 扩展。这个解析器实现了 SAX API,这是一种基于事件的解析算法。
基于事件的解析器不会将整个 XML 文档加载到内存中,而是每次读取一个节点。解析器允许您实时与之交互。一旦移动到下一个节点,先前的节点就会从内存中移除。
SAX 基于的解析机制比树状解析器更快。PHP 库包含了处理 XML 事件的函数,如本章所述。
解析 XML 文档的第一步是使用 xml_parse_create() 函数创建一个 parser 对象。
xml_parser_create(?string $encoding = null): XMLParser
此函数创建一个新的 XML parser,并返回一个 XMLParser 对象,供其他 XML 函数使用。
xml_parse() 函数开始解析 XML 文档。
xml_parse(XMLParser $parser, string $data, bool $is_final = false): int
xml_parse() 解析 XML 文档。对于配置的事件,相应的 handler 会被调用必要次数。
XMLParser 扩展提供了不同的 event handler 函数。
xml_set_element_handler()
此函数为 XML parser 设置 element handler 函数。每次 XML parser 遇到开始标签或结束标签时,就会触发 element 事件。开始标签和结束标签各有独立的 handler。
xml_set_element_handler(XMLParser $parser, callable $start_handler, callable $end_handler): true
当打开一个新的 XML element 时,会调用 start_handler() 函数;当关闭 XML element 时,会调用 end_handler() 函数。
xml_set_character_data_handler()
此函数为 XML parser 设置 character data handler 函数。Character data 大致上是 XML 文档中所有非标记内容,包括标签之间的空白字符。
xml_set_character_data_handler(XMLParser $parser, callable $handler): true
xml_set_processing_instruction_handler()
此函数为 XML parser 设置 processing instruction (PI) handler 函数。<?php ?> 是一个 processing instruction,其中 php 被称为“PI target”。这些指令的处理是特定于应用程序的。
xml_set_processing_instruction_handler(XMLParser $parser, callable $handler): true
处理指令 的格式如下 −
<?target data ?>
xml_set_default_handler()
此函数为 XML parser 设置默认 handler function。未被其他 handler 处理的内容将发送到默认 handler。您将在默认 handler 中接收到诸如 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>contact@example.com</email>
<phone>123456789</phone>
</course>
<course>
<name>Java</name>
<country>India</country>
<email>contact@example.com</email>
<phone>123456789</phone>
</course>
<course>
<name>HTML</name>
<country>India</country>
<email>contact@example.com</email>
<phone>123456789</phone>
</course>
</tutors>
示例
以下是解析上述文档的 PHP 代码。它打开 XML 文件并调用 xml_parse() 函数直到文件结束。event handlers 将数据存储在 tutors 数组中。然后逐个元素输出该数组。
<?php
// 使用 SAX(Simple API for XML) parser 读取 XML
$tutors = array();
$elements = null;
// 标签打开时调用此函数
function startElements($parser, $name, $attrs) {
global $tutors, $elements;
if(!empty($name)) {
if ($name == 'COURSE') {
// 创建数组存储信息
$tutors []= array();
}
$elements = $name;
}
}
// 标签关闭时调用此函数
function endElements($parser, $name) {
global $elements;
if(!empty($name)) {
$elements = null;
}
}
// 在标签开始和结束之间的文本内容时调用
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");
// 打开 xml 文件
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 - contact@example.com Phone - 123456789 ________________________________________ course No - 2 course Name - Java Country - India Email - contact@example.com Phone - 123456789 ________________________________________ course No - 3 course Name - HTML Country - India Email - contact@example.com Phone - 123456789 ________________________________________