PHP und XML: 使用expat函数(二)
让我们看一下实际处理这个文档的PHP代码。
/ *NewsBoy: Nachrichtensystem für das Web geschrieben in PHP von Justin Grant (Web: jusgrant.cjb.net oder justin.host.za.net Mail: justin@glendale.net)25. März V0.0.2 Newsboy wurde in eine PHP-Klasse konvertiert, sodass das Layout einfach geändert werden kann. Außerdem wurde hinzugefügt, um den generierten HTML-Code etwas leichter lesbar zu machen. 24. März V0.0.1 Habe gerade die erste Version fertiggestellt, sehr grob und einfach.*/
class newsboy { var $xml_parser; var $xml_file; var $html; var $open_tag ; var $close_tag ;
//Klassenkonstruktor
function newsboy() { $this->xml_parser = ""; $this->xml_file = ""; $this->html = ""; $this->open_tag = array(
//das sind die Standardeinstellungen, aber sie können ganz einfach geändert werden
"NEWSBOY" => "nn", "STORY" => " ", "DATE " => "", "SLUG" => " ", "TEXT" => "", "PIC" => "", "NEWLINE" => "" ); $this->close_tag = array( "NEWSBOY" => "
nnn", "STORY" => "", "DATE" => "", "SLUG" => "
", "TEXT" => "n", "PIC" => " "
" ); }
//Klassendestruktor (muss manuell aufgerufen werden, da PHP keine Destruktoren unterstützt)
function destroy() { xml_parser_free($this->xml_parser); }
//Klassenmitglieder
function concat($str) { $this->html }
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_parser, &$this); // Fallfaltung verwenden, damit wir das Tag sicher in $map_array finden
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("XML-Eingabe konnte nicht geöffnet werden"); } while ($data = fread($fp, 4096)) { if (!xml_parse($this->xml_parser, $data, feof($fp))) { die(sprintf("XML-Fehler: %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 und closeElement(当分析到一个打开或关闭标专时被分别调用)中使用 标记的名字
作为索引键值对相应的数组进行查询.如果那个键值存在,则返回值并且追加到类的'html' 属性的后面。
'html'属性将在以后我们真正显示文档内容的时候使用.
characterData方法简单地将标记之间的值加到类的html属性的后面.
被注释起来的叫PIHandler的方法是一个回调函数,我还未曾实现它。如果它存在的话,它将直接在XML
文档中处理php脚本.
Lassen Sie mich nun den Hauptaufruf der Parser-Methode erklären: parse()!!!
Die erste Zeile ruft die Funktion xml_parser_create() auf, die eine Expat-XML-Parser-Instanz zurückgibt und im gespeichert wird
attribute&this->xml_parser der Klasse.
Als nächstes müssen wir die Funktion xml_set_object() verwenden, um eine Rückruffunktion für die Klassenmethode zu registrieren.
Ich verwende es so: xml_set_object($this->xml_parser, &$this). Im ersten Parameter habe ich das Klassenattribut mit
angegeben, um den XML-Parser zu speichern, und dann habe ich im zweiten Parameter die Instanzadresse des PHP-Objekts angegeben. Dadurch weiß der Analysator, dass alle registrierten Rückruffunktionen tatsächliche Methoden der angegebenen Klasse an dieser Adresse sind. Dies ist wie eine „Referenzübergabe“ in C oder C++, manche Leute
nennen es einfach eine „Referenzvariable“.
In der nächsten Zeile rufe ich xml_parser_set_option() auf, um ein XML-Parser-Attribut unter Verwendung der Groß-/Kleinschreibung
festzulegen. Durch die Groß-/Kleinschreibung wird dem Parser lediglich mitgeteilt, dass mir beim Parsen meines XML-Dokuments die Groß-/Kleinschreibung egal ist. Wenn Sie jedoch
die Groß-/Kleinschreibung verwenden möchten, um zwei verschiedene Tags wie or zu definieren, können Sie dies tun, ohne es festzulegen hoch.
Durch die Verwendung von xml_set_element_handler() spezifiziere ich Rückruffunktionen für die Start- und End-Tags mit den Namen
"startElement" und "endElement".
Als Nächstes verwende ich xml_set_character_data_handler(), um das Zeichendatenverarbeitungshandle als Rückruffunktion mit dem Namen
characterData() anzugeben. Der mit Anmerkungen versehene Funktionsaufruf xml_set_processing_instruction_handler(),
ist derjenige, den ich zum Registrieren der Funktion PIHandler() verwendet habe. PIHandler kann in XML-Dokumente eingebunden werden, um PHP-Code zu verarbeiten.
Der Rest des Codes liest einfach die XML-Datei und analysiert sie. Wenn ein Fehler auftritt, werden die Fehlerdetails zurückgegeben, einschließlich der Zeilennummer, in der der Fehler
aufgetreten ist.