PHP 和 XML: 使用expat函数(二)
让我们看一下实际处理这个文档的PHP代码。
/*NewsBoy : News system for the web written in PHP by Justin Grant (Web: jusgrant.cjb.net or justin.host.za.net Mail: justin@glendale.net)25 March V0.0.2 Converted Newsboy to a PHP class, allowing the layout to be easily modified. Also added made the HTML that is genrated a little easier to read.24 March V0.0.1 Just completed the intial version, very rough and basic.*/
class newsboy { var $xml_parser; var $xml_file; var $html; var $open_tag ; var $close_tag ;
//Class Constructor
function newsboy() { $this->xml_parser = ""; $this->xml_file = ""; $this->html = ""; $this->open_tag = array(
//these are the default settings but they are quite easy to modify
"NEWSBOY" => "nn", "STORY" => " ", "DATE" => "", "SLUG" => " ", "TEXT" => "", "PIC" => "", "NEWLINE" => "" ); $this->close_tag = array( "NEWSBOY" => "
nnn", "STORY" => "", "DATE" => "", "SLUG" => "
", "TEXT" => "n", "PIC" => " "
" ); }
//Class Destructor (has to be invoked manually as PHP does not support destructors)
function destroy() { xml_parser_free($this->xml_parser); }
//Class Members
function concat($str) { $this->html .= $str; }
function startElement($parser, $name, $attrs) { //global $open_tag; if ($format= $this->open_tag[$name]) { $this->html .= $format; } }
function endElement($parser, $name) { global $close_tag; if ($format= $this->close_tag[$name]) { $this->html .= $format; } }
function characterData($parser, $data) { $this->html .= $data; }
/* function PIHandler($parser, $target, $data) { //switch (strtolower($target)){ // case "php": eval($data); // break; //} }*/
function parse() { $this->xml_parser = xml_parser_create(); xml_set_object($this->xml_parser, &$this); // use case-folding so we are sure to find the tag in $map_array
xml_parser_set_option($this->xml_parser, XML_OPTION_CASE_FOLDING, true); xml_set_element_handler($this->xml_parser, "startElement", "endElement"); xml_set_character_data_handler($this->xml_parser, "characterData");//xml_set_processing_instruction_handler($this->xml_parser, "PIHandler");
if (!($fp = fopen($this->xml_file, "r"))) { die("could not open XML input"); } while ($data = fread($fp, 4096)) { if (!xml_parse($this->xml_parser, $data, feof($fp))) { die(sprintf("XML error: %s at line %d", xml_error_string(xml_get_error_code($this->xml_parser)), xml_get_current_line_number($this->xml_parser))); } } }}
?>
--------------------------------------------------------------------------------
在这个类的构造函数中,我创建了打开与关闭两个标记数组。数组的关键字与我后面将要分析的标记是
一样的,并且它们相应的值包含格式化打开与关闭标记的HTML代码。
我定义了一个简单的类析构函数用来当我们不再需要它时释放XML 分析器。这个函数不得不手工调用,
因为PHP不支持当一个对象释放时自动调用类的析构函数。
然后我定义了在XML文档中用来分析打开和关闭标记的主回调方法。我也定义了一个数据分析方法, 将
用于当打开和关闭标记中有数据时,对数据进行简单的格式化,后面我将向你演示如何将这些回调方法注册
到分析器中。
在startElement和closeElement(当分析到一个打开或关闭标专时被分别调用)中使用 标记的名字
作为索引键值对相应的数组进行查询。如果那个键值存在,则返回值并且追加到类的'html' 属性的后面。
'html'属性将在以后我们真正显示文档内容的时候使用。
characterData方法简单地将标记之间的值加到类的html属性的后面。
被注释起来的叫PIHandler的方法是一个回调函数,我还未曾实现它。如果它存在的话,它将直接在XML
文档中处理php脚本。
现在,让我解释一下主要的分析方法的调用,你猜一猜,parse()!!!
第一行调用了函数xml_parser_create(),它将返回一个expat的xml分析器的实例,并且被保存在类的
属性&this->xml_parser中。
Next, we need to use the function xml_set_object() to register a callback function for the class method.
This is how I use it, xml_set_object($this->xml_parser, &$this). In the first parameter I specified the class attribute to hold the xml parser with
, and then in the second parameter I specified the instance address of the PHP object. This lets the analyzer know that all callback functions to be registered are actual methods of the specified class at that address. This is like a 'pass by reference' in c or c++, some people
simply call it a 'reference variable'.
In the next line, I call xml_parser_set_option() to set an xml parser attribute, using case
folding. Case folding just tells the parser to know that when I parse my XML document I don't care about case sensitivity, but if you
want to use case sensitivity to define two different tags like or , you can leave it unset .
By using xml_set_element_handler(), I specify callback functions for the start and end tags, named
"startElement" and "endElement".
Next, I use xml_set_character_data_handler() to specify the character data processing handle as a callback function named
characterData(). The annotated function call, xml_set_processing_instruction_handler(),
is a call I used to register the function PIHandler(). PIHandler can be included in XML documents to process PHP code.
The rest of the code simply reads the XML file and parses it. If an error occurs, the error details will be returned, including the line number where the error
occurred.
The above introduces express gate PHP and XML: using expat function 2, including the content of express gate. I hope it will be helpful to friends who are interested in PHP tutorials.