当前位置:中国站长下载文章中心网页编程PHP编程 → 用PHP读取和编写XML DOM

用PHP读取和编写XML DOM

减小字体 增大字体 作者:编辑整理  来源:互联网  发布时间:2008-9-15 22:05:05
函数。在开始和结束标记之间的文本上面,调用textData。

在这个示例中,startElement标记查找book标记,在book数组中开始一个新元素。然后,textData函数查看当前元素,看它是不是publisher、title或author标记。如果是,函数就把当前文本放入当前图书。

为了让解析继续,脚本用xml_parser_create函数创建解析器。然后,设置回调句柄。之后,脚本读取文件并把文件的大块内容发送到解析器。在文件读取之后,xml_parser_free函数删除解析器。脚本的末尾输出g_books数组的内容。

可以看到,这比编写DOM的同样功能要困难得多。如果没有DOM库也没有SAX库该怎么办?还有替代方案么?

用正则表达式解析XML

可以肯定,即使提到这个方法,有些工程师也会批评我,但是确实可以用正则表达式解析XML。清单4显示了使用preg_函数读取图书文件的示例。

清单4.用正则表达式读取XML
<?php$xml="";$f=fopen('books.xml','r');while($data=fread($f,4096)){$xml.=$data;}fclose($f);preg_match_all("/\<book\>(.*?)\<\/book\>/s",$xml,$bookblocks);foreach($bookblocks[1]as$block){preg_match_all("/\<author\>(.*?)\<\/author\>/",$block,$author);preg_match_all("/\<title\>(.*?)\<\/title\>/",$block,$title);preg_match_all("/\<publisher\>(.*?)\<\/publisher\>/",$block,$publisher);echo($title[1][0]."-".$author[1][0]."-".$publisher[1][0]."\n");}?>


请注意这个代码有多短。开始时,它把文件读进一个大的字符串。然后用一个regex函数读取每个图书项目。最后用foreach循环,在每个图书块间循环,并提取出author、title和publisher。

那么,缺陷在哪呢?使用正则表达式代码读取XML的问题是,它并没先进行检查,确保XML的格式良好。这意味着在读取之前,无法知道XML是否格式良好。而且,有些格式正确的XML可能与正则表达式不匹配,所以日后必须修改它们。

我从不建议使用正则表达式读取XML,但是有时它是兼容性最好的方式,因为正则表达式函数总是可用的。不要用正则表达式读取直接来自用户的XML,因为无法控制这类XML的格式或结构。应当一直用DOM库或SAX解析器读取来自用户的XML。

用DOM编写XML

读取XML只是公式的一部分。该怎样编写XML呢?编写XML最好的方式就是用DOM。清单5显示了DOM构建图书XML文件的方式。

 清单5.用DOM编写图书XML
<?php$books=array();$books[]=array('title'=>'PHPHacks','author'=>'JackHerrington','publisher'=>"O'Reilly");$books[]=array('title'=>'PodcastingHacks','author'=>'JackHerrington','publisher'=>"O'Reilly");$doc=newDOMDocument();$doc->formatOutput=true;$r=$doc->createElement("books");$doc->appendChild($r);foreach($booksas$book){$b=$doc->createElement("book");$author=$doc->createElement("author");$author->appendChild($doc->createTextNode($book['author']));$b->appendChild($author);$title=$doc->createElement("title");$title->appendChild($doc->createTextNode($book['title']));$b->appendChild($title);$publisher=$doc->createElement("publisher");$publisher->appendChild($doc->createTextNode($book['publisher']));$b->appendChild($publisher);$r->appendChild($b);}echo$doc->saveXML();?>

在脚本的顶部,用一些示例图书装入了books数组。这个数据可以来自用户也可以来自数据库。

示例图书装入之后,脚本创建一个newDOMDocument,并把根节点books添加到它。然后脚本为每本书的author、title和publisher创建节点,并为每个节点添加文本节点。每个book节点的最后一步是重新把它添加到根节点books。

脚本的末尾用saveXML方法把XML输出到控制台。(也可以用save方法创建一个XML文件。)脚本的输出如清单6所示。

清单6.DOM构建脚本的输出
%phpe4.php<?xmlversion="1.0"?><books><book><author>JackHerrington</author><title>PHPHacks</title><publisher>O'Reilly</publisher></book><book><author>JackHerrington</author><title>PodcastingHacks</title><publisher>O'Reilly</publisher></book></books>%

使用DOM的真正价值在于它创建的XML总是格式正确的。但是如果不能用DOM创建XML时该怎么办?

PHP编写XML

如果DOM不可用,可以用PHP的文本模板编写XML。清单7显示了PHP如何构建图书XML文件。

清单7.用PHP编写图书XML
<?php$books=array();$books[]=array('title'=>'PHPHacks','author'=>'JackHerrington','publisher'=>"O'Reilly");$books[]=array('title'=>'PodcastingHacks','author'=>'JackHerrington','publisher'=>"O'Reilly");?><books><?phpforeach($booksas$book){?><book><title><?phpecho($book['title']);?></title><author><?phpecho($book['author']);?></author><publisher><?phpecho($book['publisher']);?></publisher></book><?php}?></books>

脚本的顶部与DOM脚本类似。脚本的底部打开books标记,然后在每个图书中迭代,创建book标记和所有的内部title、author和publisher标记。

这种方法的问题是对实体进行编码。为了确保实体编码正确,必须在每个项目上调用htmlentities函数,如清单8所示。

清单8.使用htmlentities函数对实体编码
<books><?phpforeach($booksas$book){$title=htmlentities($book['title'],ENT_QUOTES);$author=htmlentities($book['author'],ENT_QUOTES);$publisher=htmlentities($book['publisher'],ENT_QUOTES);?><book><title><?phpecho($title);?></title><author><?phpecho($author);?></author><publisher><?phpecho($publisher);?></publisher></book><?php}?></books>

这就是用基本的PHP编写XML的烦人之处。您以为自己创建了完美的XML,但是在试图使用数据的时候,马上就会发现某些元素的编码不正确。

结束语

XML周围总有许多夸大之处和混淆之处。但是,并不像您想像的那么难——特别是在PHP这样优秀的语言中。在理解并正确地实现了XML之后,就会发现有许多强大的工具可以使用。XPath和XSLT就是这样两个值得研究的工具。

上一页  [1] [2]