用 PHP 读取和编写 XML DOM.docx

上传人:b****7 文档编号:9977601 上传时间:2023-02-07 格式:DOCX 页数:44 大小:46.04KB
下载 相关 举报
用 PHP 读取和编写 XML DOM.docx_第1页
第1页 / 共44页
用 PHP 读取和编写 XML DOM.docx_第2页
第2页 / 共44页
用 PHP 读取和编写 XML DOM.docx_第3页
第3页 / 共44页
用 PHP 读取和编写 XML DOM.docx_第4页
第4页 / 共44页
用 PHP 读取和编写 XML DOM.docx_第5页
第5页 / 共44页
点击查看更多>>
下载资源
资源描述

用 PHP 读取和编写 XML DOM.docx

《用 PHP 读取和编写 XML DOM.docx》由会员分享,可在线阅读,更多相关《用 PHP 读取和编写 XML DOM.docx(44页珍藏版)》请在冰豆网上搜索。

用 PHP 读取和编写 XML DOM.docx

用PHP读取和编写XMLDOM

用PHP读取和编写可扩展标记语言(XML)看起来可能有点恐怖。

实际上,XML和它的所有相关技术可能是恐怖的,但是用PHP读取和编写XML不一定是项恐怖的任务。

首先,需要学习一点关于XML的知识——它是什么,用它做什么。

然后,需要学习如何用PHP读取和编写XML,而有许多种方式可以做这件事。

本文提供了XML的简短入门,然后解释如何用PHP读取和编写XML。

什么是XML?

XML是一种数据存储格式。

它没有定义保存什么数据,也没有定义数据的格式。

XML只是定义了标记和这些标记的属性。

格式良好的XML标记看起来像这样:

JackHerrington

这个标记包含一些文本:

JackHerrington。

不包含文本的XML标记看起来像这样:

用XML对某件事进行编写的方式不止一种。

例如,这个标记形成的输出与前一个标记相同:

也可以向XML标记添加属性。

例如,这个标记包含first和last属性:

也可以用XML对特殊字符进行编码。

例如,&符号可以像这样编码:

&

包含标记和属性的XML文件如果像示例一样格式化,就是格式良好的,这意味着标记是对称的,字符的编码正确。

清单1是一份格式良好的XML的示例。

清单1.XML图书列表示例

JackHerrington

PHPHacks

O'Reilly

JackHerrington

PodcastingHacks

O'Reilly

清单1中的XML包含一个图书列表。

父标记包含一组标记,每个标记又包含和<publisher>标记。</p><p>当XML文档的标记结构和内容得到外部模式文件的验证后,XML文档就是正确的。</p><p>模式文件可以用不同的格式指定。</p><p>对于本文来说,所需要的只是格式良好的XML。</p><p>如果觉得XML看起来很像超文本标记语言(HTML),那么就对了。</p><p>XML和HTML都是基于标记的语言,它们有许多相似之处。</p><p>但是,要着重指出的是:</p><p>虽然XML文档可能是格式良好的HTML,但不是所有的HTML文档都是格式良好的XML。</p><p>换行标记(br)是XML和HTML之间区别的一个好例子。</p><p>这个换行标记是格式良好的HTML,但不是格式良好的XML:</p><p><p>Thisisaparagraph<br></p><p>Withalinebreak</p></p><p>这个换行标记是格式良好的XML和HTML:</p><p><p>Thisisaparagraph<br/></p><p>Withalinebreak</p></p><p>如果要把HTML编写成同样是格式良好的XML,请遵循W3C委员会的可扩展超文本标记语言(XHTML)标准(参见参考资料)。</p><p>所有现代的浏览器都能呈现XHTML。</p><p>而且,还可以用XML工具读取XHTML并找出文档中的数据,这比解析HTML容易得多。</p><p>回页首</p><p>使用DOM库读取XML</p><p>读取格式良好的XML文件最容易的方式是使用编译成某些PHP安装的文档对象模型(DOM)库。</p><p>DOM库把整个XML文档读入内存,并用节点树表示它,如图1所示。</p><p>图1.图书XML的XMLDOM树</p><p>树顶部的books节点有两个book子标记。</p><p>在每本书中,有author、publisher和title几个节点。</p><p>author、publisher和title节点分别有包含文本的文本子节点。</p><p>读取图书XML文件并用DOM显示内容的代码如清单2所示。</p><p>清单2.用DOM读取图书XML</p><p><?</p><p>php</p><p>$doc=newDOMDocument();</p><p>$doc->load('books.xml');</p><p>$books=$doc->getElementsByTagName("book");</p><p>foreach($booksas$book)</p><p>{</p><p>$authors=$book->getElementsByTagName("author");</p><p>$author=$authors->item(0)->nodeValue;</p><p>$publishers=$book->getElementsByTagName("publisher");</p><p>$publisher=$publishers->item(0)->nodeValue;</p><p>$titles=$book->getElementsByTagName("title");</p><p>$title=$titles->item(0)->nodeValue;</p><p>echo"$title-$author-$publisher\n";</p><p>}</p><p>?</p><p>></p><p>脚本首先创建一个newDOMdocument对象,用load方法把图书XML装入这个对象。</p><p>之后,脚本用getElementsByName方法得到指定名称下的所有元素的列表。</p><p>在book节点的循环中,脚本用getElementsByName方法获得author、publisher和title标记的nodeValue。</p><p>nodeValue是节点中的文本。</p><p>脚本然后显示这些值。</p><p>可以在命令行上像这样运行PHP脚本:</p><p>%phpe1.php</p><p>PHPHacks-JackHerrington-O'Reilly</p><p>PodcastingHacks-JackHerrington-O'Reilly</p><p>%</p><p>可以看到,每个图书块输出一行。</p><p>这是一个良好的开始。</p><p>但是,如果不能访问XMLDOM库该怎么办?</p><p>回页首</p><p>用SAX解析器读取XML</p><p>读取XML的另一种方法是使用XMLSimpleAPI(SAX)解析器。</p><p>PHP的大多数安装都包含SAX解析器。</p><p>SAX解析器运行在回调模型上。</p><p>每次打开或关闭一个标记时,或者每次解析器看到文本时,就用节点或文本的信息回调用户定义的函数。</p><p>SAX解析器的优点是,它是真正轻量级的。</p><p>解析器不会在内存中长期保持内容,所以可以用于非常巨大的文件。</p><p>缺点是编写SAX解析器回调是件非常麻烦的事。</p><p>清单3显示了使用SAX读取图书XML文件并显示内容的代码。</p><p>清单3.用SAX解析器读取图书XML</p><p><?</p><p>php</p><p>$g_books=array();</p><p>$g_elem=null;</p><p>functionstartElement($parser,$name,$attrs)</p><p>{</p><p>global$g_books,$g_elem;</p><p>if($name=='BOOK')$g_books[]=array();</p><p>$g_elem=$name;</p><p>}</p><p>functionendElement($parser,$name)</p><p>{</p><p>global$g_elem;</p><p>$g_elem=null;</p><p>}</p><p>functiontextData($parser,$text)</p><p>{</p><p>global$g_books,$g_elem;</p><p>if($g_elem=='AUTHOR'||</p><p>$g_elem=='PUBLISHER'||</p><p>$g_elem=='TITLE')</p><p>{</p><p>$g_books[count($g_books)-1][$g_elem]=$text;</p><p>}</p><p>}</p><p>$parser=xml_parser_create();</p><p>xml_set_element_handler($parser,"startElement","endElement");</p><p>xml_set_character_data_handler($parser,"textData");</p><p>$f=fopen('books.xml','r');</p><p>while($data=fread($f,4096))</p><p>{</p><p>xml_parse($parser,$data);</p><p>}</p><p>xml_parser_free($parser);</p><p>foreach($g_booksas$book)</p><p>{</p><p>echo$book['TITLE']."-".$book['AUTHOR']."-";</p><p>echo$book['PUBLISHER']."\n";</p><p>}</p><p>?</p><p>></p><p>脚本首先设置g_books数组,它在内存中容纳所有图书和图书信息,g_elem变量保存脚本目前正在处理的标记的名称。</p><p>然后脚本定义回调函数。</p><p>在这个示例中,回调函数是startElement、endElement和textData。</p><p>在打开和关闭标记的时候,分别调用startElement和endElement函数。</p><p>在开始和结束标记之间的文本上面,调用textData。</p><p>在这个示例中,startElement标记查找book标记,在book数组中开始一个新元素。</p><p>然后,textData函数查看当前元素,看它是不是publisher、title或author标记。</p><p>如果是,函数就把当前文本放入当前图书。</p><p>为了让解析继续,脚本用xml_parser_create函数创建解析器。</p><p>然后,设置回调句柄。</p><p>之后,脚本读取文件并把文件的大块内容发送到解析器。</p><p>在文件读取之后,xml_parser_free函数删除解析器。</p><p>脚本的末尾输出g_books数组的内容。</p><p>可以看到,这比编写DOM的同样功能要困难得多。</p><p>如果没有DOM库也没有SAX库该怎么办?</p><p>还有替代方案么?</p><p>回页首</p><p>用正则表达式解析XML</p><p>可以肯定,即使提到这个方法,有些工程师也会批评我,但是确实可以用正则表达式解析XML。</p><p>清单4显示了使用preg_函数读取图书文件的示例。</p><p>清单4.用正则表达式读取XML</p><p><?</p><p>php</p><p>$xml="";</p><p>$f=fopen('books.xml','r');</p><p>while($data=fread($f,4096)){$xml.=$data;}</p><p>fclose($f);</p><p>preg_match_all("/\<book\>(.*?</p><p>)\<\/book\>/s",</p><p>$xml,$bookblocks);</p><p>foreach($bookblocks[1]as$block)</p><p>{</p><p>preg_match_all("/\<author\>(.*?</p><p>)\<\/author\>/",</p><p>$block,$author);</p><p>preg_match_all("/\<title\>(.*?</p><p>)\<\/title\>/",</p><p>$block,$title);</p><p>preg_match_all("/\<publisher\>(.*?</p><p>)\<\/publisher\>/",</p><p>$block,$publisher);</p><p>echo($title[1][0]."-".$author[1][0]."-".</p><p>$publisher[1][0]."\n");</p><p>}</p><p>?</p><p>></p><p>请注意这个代码有多短。</p><p>开始时,它把文件读进一个大的字符串。</p><p>然后用一个regex函数读取每个图书项目。</p><p>最后用foreach循环,在每个图书块间循环,并提取出author、title和publisher。</p><p>那么,缺陷在哪呢?</p><p>使用正则表达式代码读取XML的问题是,它并没先进行检查,确保XML的格式良好。</p><p>这意味着在读取之前,无法知道XML是否格式良好。</p><p>而且,有些格式正确的XML可能与正则表达式不匹配,所以日后必须修改它们。</p><p>我从不建议使用正则表达式读取XML,但是有时它是兼容性最好的方式,因为正则表达式函数总是可用的。</p><p>不要用正则表达式读取直接来自用户的XML,因为无法控制这类XML的格式或结构。</p><p>应当一直用DOM库或SAX解析器读取来自用户的XML。</p><p>回页首</p><p>用DOM编写XML</p><p>读取XML只是公式的一部分。</p><p>该怎样编写XML呢?</p><p>编写XML最好的方式就是用DOM。</p><p>清单5显示了DOM构建图书XML文件的方式。</p><p>清单5.用DOM编写图书XML</p><p><?</p><p>php</p><p>$books=array();</p><p>$books[]=array(</p><p>'title'=>'PHPHacks',</p><p>'author'=>'JackHerrington',</p><p>'publisher'=>"O'Reilly"</p><p>);</p><p>$books[]=array(</p><p>'title'=>'PodcastingHacks',</p><p>'author'=>'JackHerrington',</p><p>'publisher'=>"O'Reilly"</p><p>);</p><p>$doc=newDOMDocument();</p><p>$doc->formatOutput=true;</p><p>$r=$doc->createElement("books");</p><p>$doc->appendChild($r);</p><p>foreach($booksas$book)</p><p>{</p><p>$b=$doc->createElement("book");</p><p>$author=$doc->createElement("author");</p><p>$author->appendChild(</p><p>$doc->createTextNode($book['author'])</p><p>);</p><p>$b->appendChild($author);</p><p>$title=$doc->createElement("title");</p><p>$title->appendChild(</p><p>$doc->createTextNode($book['title'])</p><p>);</p><p>$b->appendChild($title);</p><p>$publisher=$doc->createElement("publisher");</p><p>$publisher->appendChild(</p><p>$doc->createTextNode($book['publisher'])</p><p>);</p><p>$b->appendChild($publisher);</p><p>$r->appendChild($b);</p><p>}</p><p>echo$doc->saveXML();</p><p>?</p><p>></p><p>在脚本的顶部,用一些示例图书装入了books数组。</p><p>这个数据可以来自用户也可以来自数据库。</p><p>示例图书装入之后,脚本创建一个newDOMDocument,并把根节点books添加到它。</p><p>然后脚本为每本书的author、title和publisher创建节点,并为每个节点添加文本节点。</p><p>每个book节点的最后一步是重新把它添加到根节点books。</p><p>脚本的末尾用saveXML方法把XML输出到控制台。</p><p>(也可以用save方法创建一个XML文件。</p><p>)脚本的输出如清单6所示。</p><p>清单6.DOM构建脚本的输出</p><p>%phpe4.php</p><p><?</p><p>xmlversion="1.0"?</p><p>></p><p><books></p><p><book></p><p><author>JackHerrington</author></p><p><title>PHPHacks

O'Reilly

JackHerrington

PodcastingHacks

O'Reilly

%

使用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"

);

?

>

php

foreach($booksas$book)

{

?

>

<?</p><p>phpecho($book['title']);?</p><p>>

phpecho($book['author']);?

>

phpecho($book['publisher']);?

>

php

}

?

>

脚本的顶部与DOM脚本类似。

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

这种方法的问题是对实体进行编码。

为了确保实体编码正确,必须在每个项目上调用htmlentities函数,如清单8所示。

清单8.使用htmlentities函数对实体编码

php

foreach($booksas$book)

{

$title=htmlentities($book['title'],ENT_QUOTES);

$author=htmlentities($book['author'],ENT_QUOTES);

$publisher=htmlentities($book['publisher'],ENT_QUOTES);

?

>

<?</p><p>phpecho($title);?</p><p>>

phpecho($author);?

>

phpecho($publisher);?

>

php

}

?

>

这就是用基本的PHP编写XML的烦人之处。

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

回页首

结束语

XML周围总有许多夸大之处和混淆之处。

但是,并不像您想像的那么难——特别是在PHP这样优秀的语言中。

在理解并正确地实现了XML之后,就会发现有许多强大的工具可以使用。

XPath和XSLT就是这样两个值得研究的工具。

参考资料

∙学习

您可以参阅本文在developerWorks全球站点上的英文原文。

∙在XHTML1.0TheExtensibleHyperTextMarkupLanguage上学习XHTML的标准。

∙找到standardsforXML。

∙了解XMLPath(XPath)language。

∙了解XSLTransformations,这是用于转换XML的语言。

∙请阅读用来定义XML文档结构的标准XMLSchema。

∙在developerWorks的XML专区找到面向XML开发人员的更多资源。

∙请访问developerWorks的开放源码专区获得全面的how-to信息、工具和项目更新,帮助您用开放源码技术开发并把它们用于IBM产品。

获得产品和技术

请访问PHP.net,了解关于PHP的最新新闻、找到下载,并向其他用户学习。

∙了解ExpatXMLParser,这个解析器用来向PHP提供SAX解析器功能。

∙利用IBM试用软件改造您的下一个开放源码开发项目,可以下载也可以通过DVD得到。

讨论

通过参与developerWorksblogs加入developerWorks社区。

关于作者

JackD.Herrington是有20多年经验的高级软件工程师。

他是三本书的作者:

CodeGenerationinAction、PodcastingHacks和即将发表的PHPHacks。

他还撰写了30多篇文章。

posted@2008-07-2210:

49十三郎阅读(30)|评论(0)|编辑收藏

LAMP优化

  [LAMP平台]

  LAMP这个词的由来最早始于德国杂志“c'tMagazine”,MichaelKunze在1990年最先把这些项目组合在一起创造了LAMP的缩写字。

这些组件虽然并不是开开始就设计为一起使用的,但是,这些开源软件都可以很方便的随时获得并免费获得。

这就导致了这些组件经常在一起

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > IT计算机 > 计算机硬件及网络

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1