用PHP工具包expat解析XML
發(fā)表時間:2023-08-14 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]如今人人鼓吹XML是Web開發(fā)者最好的朋友,有了XML的幫忙,后者即可輕松地格式化和顯示來自幾乎任何數(shù)據(jù)源的數(shù)據(jù)。但是,對動態(tài)內(nèi)容而言,格式優(yōu)良的數(shù)據(jù)卻還遠(yuǎn)遠(yuǎn)談不上達(dá)到理想狀態(tài)。大多數(shù)的Web開發(fā)者...
如今人人鼓吹XML是Web開發(fā)者最好的朋友,有了XML的幫忙,后者即可輕松地格式化和顯示來自幾乎任何數(shù)據(jù)源的數(shù)據(jù)。但是,對動態(tài)內(nèi)容而言,格式優(yōu)良的數(shù)據(jù)卻還遠(yuǎn)遠(yuǎn)談不上達(dá)到理想狀態(tài)。大多數(shù)的Web開發(fā)者都會告訴你,今天的網(wǎng)絡(luò)上沒有動態(tài)內(nèi)容怎么能行!問題是:“到底該如何用XML創(chuàng)建動態(tài)內(nèi)容呢?”
答案是用動態(tài)內(nèi)容處理語言來解析XML,比如用PHP或者Perl等,從理論上說,這類程序語言是可以出于各種目的利用XML的。無非是采用一些能解析XML的工具包而已。James Clark就提供了一種名叫expat的工具包。expat XML工具包用C語言解析XML,令PHP與XML輕松共舞。
PHP是一種專為Web設(shè)計的絕佳腳本語言。XML是表示W(wǎng)eb內(nèi)容的標(biāo)準(zhǔn)。兩者聯(lián)手真是要多美有多美!
下面我會給讀者演示一個簡單的示例,通過這個例子即可說明如何用PHP把XML文檔解析為HTML。然后我會介紹一些PHP的其他XML概念。用PHP解析XML很簡單,操作起來很直觀但卻需要對細(xì)節(jié)有所解釋。一旦真正掌握了應(yīng)用的要領(lǐng),你肯定會驚奇自己怎么不早想到把它們倆攏一塊兒來。
概述
PHP用expat這種XML工具包,通過C語言來解析XML。這個工具包的函數(shù)集同Perl XML解析所采用的函數(shù)集是一樣的,此外,這種工具包還是事件驅(qū)動型的解析器。這就是說,expat把每個XML標(biāo)簽或者新一行代碼當(dāng)作事件的起始,而事件就是函數(shù)的觸發(fā)器。Expat的安裝非常簡單,如果你正在用著Apache Web服務(wù)器,那么你可以在PHP XML參考頁上找到安裝和下載指南。
用PHP解析XML的基本任務(wù)是這樣的:首先,創(chuàng)建XML解析器的一個實(shí)例。接著,定義處理觸發(fā)事件的函數(shù),比如開始或者結(jié)束標(biāo)簽等。隨后,定義實(shí)際意義的數(shù)據(jù)處理程序。最后,打開XML文件,讀取文件數(shù)據(jù)并解析數(shù)據(jù)。之后關(guān)閉文件釋放XML解析器。
你瞧,就像我說的那樣,這套操作過程沒什么特別的。不過,在我們討論具體的示例之前先了解以下的一些警示:
Expat不對XML進(jìn)行檢驗。這意味著只要XML文件格式正確——所有的元素嵌套得當(dāng)、開始和關(guān)閉標(biāo)簽沒有任何錯誤——它就會被解析。Expat可不管XML是否遵守XML文件頭中引用的標(biāo)準(zhǔn)或者定義。
Expat把XML標(biāo)簽全部轉(zhuǎn)換為大寫字母。如果你的腳本在標(biāo)簽名和其他內(nèi)容上大小寫字母混用可就要小心了。
PHP是在magic quotes設(shè)置啟用的情況下編譯而成,那么復(fù)雜的XML文件不會得到正確的解析。要是magic quotes不是默認(rèn)設(shè)置,你就當(dāng)我沒說。
好了,我們現(xiàn)在就來看看有關(guān)的示例!
基本示例
為了把復(fù)雜的事情簡單化,我在例子中省略了錯誤檢查和其他一些不必要的東西,當(dāng)然,你可以在自己的代碼隨心所欲。我假定你早就熟悉PHP及其語法,而我會對XML函數(shù)做一番解釋。首先我會說明腳本程序的含義,接著定義用戶定義函數(shù),實(shí)際上這些函數(shù)位于引用它們的代碼之前。相關(guān)附件:程序清單A 所示為腳本的完整代碼,腳本要解析的XML文檔則是 相關(guān)附件:程序清單B。處理之后的輸出結(jié)果如表A所示。
XML Articles
"Remedial XML for programmers: Basic syntax" In this first installment in a three-part series, I'll introduce you to XML and its basic syntax.
"Remedial XML: Enforcing document formats with DTDs" To enforce structure requirements for an XML document, you have to turn to one of XML's attendant technologies, data type definition (DTD).
"Remedial XML: Using XML Schema" In this article, we'll briefly touch on the shortcomings of DTDs and discuss the basics of a newer, more powerful standard: XML Schemas.
"Remedial XML: Say hello to DOM" Now it's time to put on your programmer's hat and get acquainted with Document Object Model (DOM), which provides easy access to XML documents via a tree-like set of objects.
"Remedial XML: Learning to play SAX" In this fifth installment in our Remedial XML series, I'll introduce you to the SAX API and provide some links to SAX implementations in several languages.
表A PHP解析XML的輸出結(jié)果
首先我創(chuàng)建了XML解析器的一個實(shí)例:
$parser = xml_parser_create();
接著,我定義解析器遭遇開始和結(jié)束標(biāo)簽時的操作。注意“startElement”和“endElement”是用戶定義的函數(shù),當(dāng)然你可以按照自己的喜好給它們起個其他名字,但我起的這些名字可是標(biāo)準(zhǔn)的習(xí)慣要求。
xml_set_element_handler($parser, “startElement”, “endElement”);
然后我定義了數(shù)據(jù)操作。這里的“characterData”也是用戶定義的函數(shù),名字也是習(xí)慣性的。
xml_set_character_data_handler($parser, “characterData”);
現(xiàn)在打開文件讀取數(shù)據(jù)。你可以在這里開始編寫錯誤處理代碼,我在例子中省略了這些錯誤處理。不要忘了在腳本的開頭定義$xml_file。
$filehandler = fopen($xml_file, “r”);
我開始讀取文件內(nèi)容,一次讀4K字節(jié)并放在變量“$data”內(nèi)直到文件末尾。我用xml_parse解析讀取的這些數(shù)據(jù)段。
while ($data = fread($filehandler, 4096)) {
xml_parse($parser, $data, feof($filehandler));
}
最后進(jìn)行清空、關(guān)閉文件和釋放解析器等操作。
fclose($filehandler);
xml_parser_free($parser);
以上就是腳本中所用到的所有XML函數(shù),下面我再具體解釋下其中用到的3個用戶定義函數(shù),它們就是“startElement”、“endElement”和“characterData”。
只要xml_parse遇到<url>這樣的開始標(biāo)簽,“startElement”函數(shù)就由XML解析器調(diào)用,在我們的例子中解析器就是$parser。該函數(shù)是必須定義的函數(shù),它擁有3個自動傳遞給它的參數(shù):XML解析器實(shí)例、大寫的元素名稱,比如URL以及該元素所具有的屬性數(shù)組。在以上示例中,XML文件中的元素沒有屬性集合,所以數(shù)組參數(shù)為空,但這個參數(shù)還是必須存在的。
就這個例子而言,我決定在一個HTML表中顯示我的XML數(shù)據(jù)。如上所示,出于簡化的緣故我沒有編寫錯誤處理代碼。這里我耍了個障眼法,因為我知道XML文件中標(biāo)簽出現(xiàn)的順序。否則我可以用“startElement”、“characterData”和“endElement”函數(shù)來定義數(shù)組,然后用單獨(dú)的函數(shù)顯示結(jié)果。
function startElement($parser_instance, $element_name, $attrs) {
switch($element_name) {
case “URL” : echo “<tr><td><a href=””;
break;
case “SUMMARY” : echo “<td>”;
break;
}
}
處理元素標(biāo)簽之后,xml_parse一旦遇到XML數(shù)據(jù)就會調(diào)用“characterData”函數(shù)。這個函數(shù)也是由解析器自動調(diào)用的,該函數(shù)需要兩個參數(shù),解析器實(shí)例和包含數(shù)據(jù)的字符串。
function characterData($parser_instance, $xml_data) {
echo $xml_data;
}
最后xml_parse遭遇結(jié)束標(biāo)簽,運(yùn)行“endElement”函數(shù),該函數(shù)帶兩個參數(shù),解析器實(shí)例和元素名稱。
function endElement($parser_instance, $element_name) {
switch($element_name) {
case “URL” : echo “”>”;
break;
case “TITLE” : echo “</a></td>”;
break;
case “SUMMARY” : echo “</td></tr>”;
break;
}
}
用PHP解析XML的輕量鍛煉到這里就結(jié)束了,下面我們開始加些重活。
增加函數(shù)
PHP中還有其他一些同XML解析有關(guān)的函數(shù)。PHP.net文檔對這些函數(shù)進(jìn)行了完整的說明。我在這里提到了一些,你或許不久就會用到這些函數(shù):
xml_set_default_handler()—該函數(shù)的工作方式和xml_set_character_data_handler()函數(shù)相近,但它捕獲定義的一切。這個函數(shù)常用于文檔類型聲明控制數(shù)據(jù)的處理。
xml_parser_set_option()—你可以用這個函數(shù)禁用字母的轉(zhuǎn)大寫操作或者選擇其他替代的字符編碼集。
xml_parse_into_struct()—這個函數(shù)用來略過“startElement”、“characterData”和“endElement”函數(shù)的調(diào)用,而把數(shù)據(jù)直接放進(jìn)數(shù)組。
xml_error_string()—這個函數(shù)用來從xml_parser() 錯誤中獲取文本信息。
xml_get_error_code()—你可以用這個函數(shù)獲取上面提到的錯誤字符串。后兩個函數(shù)的用法是這樣的:if(!xml_parse($parser, $data, feof($filehandler))) { die(xml_error_string(xml_get_error_code($parser)); )
如果你覺得自己已經(jīng)上手,我建議你仔細(xì)讀讀PHP手冊頁中提供的XML External Entity Example。這些例子提出了本文沒有提到的其他一些概念以及處理文件錯誤的某些技術(shù)。
小結(jié)
本文演示了PHP和XML的緊密結(jié)合過程。兩種技術(shù)以Web為中心的天性促使它們聯(lián)合起來成為動態(tài)內(nèi)容所需的理想解決方案。