首頁  >  文章  >  後端開發  >  export_symbol php xml分析函數程式碼第1/2頁

export_symbol php xml分析函數程式碼第1/2頁

WBOY
WBOY原創
2016-07-29 08:38:441036瀏覽

首先我得承認我喜歡計算機標準。如果每個人都遵從這個行業的標準,網路將會是更好的媒體。使用標準化的資料交換格式才能使開放的和獨立於平台的計算模式切實可行。這就是我作為XML愛好者的原因。
幸運的是,我最愛的腳本語言不但支援XML而且對其支援正不斷加強。 PHP可以讓我迅速將XML文件發佈到互聯網上,收集XML文檔的統計信息,將XML文檔轉換成其它格式。例如,我時常用PHP的XML處理能力來管理我用XML所寫的文章和書。
本文中,我將討論任何用PHP內建的Expat解析器來處理XML文件。透過範例,我將示範Expat的處理方法。同時,範例可以告訴你
如何:
建立自己的處理函數
將XML文件轉換成你自己的PHP資料結構
介紹Expat
XML的解析器,同樣稱為XML處理器,可使程式存取XML文件的結構和內容。 Expat是PHP腳本語言的XML解析器。它同時也運用在
其它專案中,例如Mozilla、Apache和Perl。
什麼是基於事件的解析器?
XML解析器的兩種基本類型:
基於樹型的解析器:將XML文件轉換成樹型結構。這類解析器分析整篇文章,同時提供一個API來存取所產生樹的每個元素。其通
用的標準為DOM(文檔物件模式)。
基於事件的解析器:將XML文件視為一系列的事件。當一個特殊事件發生時,解析器會呼叫開發者提供的函數來處理。
基 於事件的解析器有一個XML文件的資料集中視圖,也就是說它集中在XML文件的資料部分,而不是其結構。這些解析器從頭到尾
處理文檔,並將類似於-元素的 開始、元素的結尾、特徵資料的開始等等——事件透過回呼(callback)函數報告給應用程式。以
下是一個"Hello-World"的XML文檔範例:

Hello World

基於事件的解析器將報告為三個事件:
開始元素:greeting
CDATA項目的開始,值為:Hello World
結束元素:greeting
不像基於樹型的解析器,基於事件的解析器不產生描述文件的結構。在CDATA項中,基於事件的解析器不會讓你得到父元素
greeting的資訊。
然而,它提供一個更底層的訪問,這使得可以更好地利用資源和更快地訪問。透過這種方式,就沒有必要將整個文件放入記憶體
;而事實上,整個文件甚至可以大於實際記憶體值。
Expat就是這樣的一種基於事件的解析器。當然如果使用Expat,必要時它一樣可以在PHP中產生完全的原生樹結構。
上面Hello-World的範例包括完整的XML格式。但它是無效的,因為既沒有DTD(文件類型定義)與其聯繫,也沒有內嵌DTD。
對於Expat,這並沒有區別:Expat是一個不檢查有效性的解析器,因此忽略任何與文件聯繫的DTD。但要注意的是文件仍需要完
整的格式,否則Expat(和其他符合XML標準的解析器一樣)將會隨著出錯訊息而停止。
作為不檢查有效性的解析器,Exapt的快速性和輕巧性使其十分適合互聯網程序。
編譯Expat
Expat可以編譯進PHP3.0.6版本(或以上)。從Apache1.3.9開始,Expat已經作為Apache的一部分。在Unix系統中,透過-with
-xml選項來設定PHP,你可以將其編譯入PHP。
如果你將PHP編譯為Apache的模組,而Expat將預設為Apache的一部分。在Windows中,你則必須載入XML動態連線庫。
XML範例:XMLstats
了解Expat的函數的一個方法就是透過範例。我們要討論的範例是使用Expat來收集XML文件的統計資料。
對於文件中每個元素,以下資訊都會被輸出:
該元素在文件中使用的次數
該元素中字元資料的數量
元素的父元素
元素的子元素
注意:為了演示,我們利用PHP來產生一個結構來保存元素的父元素和子元素
準備
用於產生XML解析器實例的函數為xml_parser_create()。該實例將用於以後的所有函數。這個想法非常類似PHP中MySQL函數的
連接 標記。在解析文件前,基於事件的解析器通常要求你註冊回調函數-用於特定的事件發生時呼叫。Expat沒有例外事件,它
定義瞭如下七個可能事件:
對象XML解析函數描述
元素xml_set_element_handler() 元素的開始和結束
字符數據xml_set_character_data_handler() 字符數據的開始
外部實體xml_set_external_entity_ref_handler() 外部實體出現
未解析外部實體xml_set_unparsed_entity_decl_handler() 未解析的外部實體出現
處理指令說明的出現
預設xml_set_default_handler() 其它沒有指定處理函數的事件
所有的回呼函數必須將解析器的實例作為其第一個參數(此外還有其它參數)。
對於本文最後的範例腳本。你需要注意的是它既用到了元素處理函數又用到了字元資料處理函數。元素的回呼處理函數透過
xml_set_element_handler()來註冊。
這個函數需要三個參數:
解析器的實例
處理開始元素的回調函數的名稱
處理結束元素的回呼函數的名稱
當開始解析XML文件時,回調函數必須存在。它們必須定義為與PHP手冊中所描述的原型一致。
例如,Expat將三個參數傳遞給開始元素的處理函數。在腳本範例中,其定義如下:
function start_element($parser, $name, $attrs)
第一個參數是解析器標示,第二個參數是開始元素的名稱,第三參數為包含元素所有屬性和值的陣列。
一旦你開始解析XML文檔,Expat在遇到開始元素是都會呼叫你的start_element()函數並將參數傳遞過去。
XML的Case Folding選項
用xml_parser_set_option ()函式將Case folding選項關閉。這個選項預設是開啟的,使得傳遞給處理函數的元素名稱自動轉換為
大寫。但XML對大小寫是敏感的(所以大小寫對統計XML文件是非 常重要的)。對於我們的範例,case folding選項必須關閉。
解析文檔
在完成所有的準備工作後,現在腳本終於可以解析XML文檔:
Xml_parse_from_file(),一個自定義的函數,打開參數中指定的文件,並以4kb的大小進行解析
xml_parse()和xml_parse_from_file()一樣,當發生錯誤時,即XML文件的格式不完全時,將會傳回false。
你可以使用xml_get_error_code()函數來得到最後一個錯誤的數字碼。將此數字代碼傳遞給xml_error_string()函數即可得到
錯誤的文字訊息。
輸出XML目前的行數,使得偵錯更容易。
在解析的過程中,呼叫回調函數。
描述文件結構
當解析文件時,對於Expat需要強調問題的是:如何保持文件結構的基本描述?
如前所述,基於事件的解析器本身並不會產生任何結構資訊。
不 過標籤(tag)結構是XML的重要特性。例如,元素序列表示的意思不同於<title>。也就是說,任何作 <br>者都會告訴你書名和圖名是沒有關係的,雖然它們都用到"title"這個術語。因此, 為了更有效地使用基於事件的解析器處理XML <br>,你必須使用自己的堆疊(stacks)或列表(lists)來維護文件的結構資訊。 <br>為了產生文件結構的鏡像,腳本至少需要知道目前元素的父元素。用Exapt的API是無法實現的,它只報告目前元素的事件,而沒 <br>有任何前後關係的資訊。因此,你需要建立自己的堆疊結構。 <br>腳本範例使用先進後出(FILO)的堆疊結構。透過一個數組,堆疊將保存全部的開始元素。對於開始元素處理函數,目前的元素將被 <br>array_push()函數推到堆疊的頂部。對應的,結束元素處理函數透過array_pop()將最頂的元素移走。 <br>對於序列<book><title>,棧的填充如下:
開始元素book:將"book"賦給棧的第一個元素($stack[0] )。
開始元素title:將"title"賦給堆疊的頂端($stack[1])。
結束元素title:從堆疊中將最頂端的元素移去($stack[1])。
結束元素title:從堆疊中將最頂端的元素移去($stack[0])。
PHP3.0透過一個$depth變數手動控制元素的巢狀來實現範例。這就使腳本看起來比較複雜。 PHP4.0透過array_pop()和
array_push()兩個函數來讓腳本看起來更簡潔。
收集資料
為了收集每個元素的信息,腳本需要記住每個元素的事件。透過使用一個全域的陣列變數$elements來保存文件中所有不同的元素
。陣列的項目是元素類別的實例,有4個屬性(類別的變數)
$count -該元素在文件中被發現的次數
$chars -元素中字元事件的位元組數
$parents -父元素
$childs - 子元素
正如你所看到的,將類別實例保存在陣列中是輕而易舉的。
注意:PHP的一個特性是你可以透過while(list() = each())loop遍歷整個類別結構,如同你遍歷整個對應的陣列一樣。所有的類別變
量(當你用PHP3.0時還有方法名稱)都以字串的方式輸出。
當發現一個元素時,我們需要增加其對應的記數器來追蹤它在文件中出現多少次。在對應的$elements項中的記數元素也要加一。
我們同樣要讓父元素知道目前的元素是它的子元素。因此,目前元素的名稱將會加入到父元素的$childs陣列的項目中。最後,目
前元素應該記住誰是它的父元素。所以,父元素被加入到目前元素$parents陣列的項目中。
顯示統計資訊
剩下的程式碼在$elements數組和其子數組中循環顯示其統計結果。這就是最簡單的巢狀循環,儘管輸出正確的結果,但程式碼既不簡
潔又沒有任何特別的技巧,它只是一個你可能每天用他來完成工作的循環。
腳本範例被設計為透過PHP的CGI方式的命令列來呼叫。因此,統計結果輸出的格式為文字格式。如果你要將腳本運用在網路上
,那麼你需要修改輸出函數來產生HTML格式。
總結
Exapt是PHP的XML解析器。作為基於事件的解析器,它不產生文件的結構描述。但透過提供底層訪問,這使得可以更好地利用資
來源和更快地訪問。
作為一個不檢查有效性的解析器,Expat忽略與XML文件連接的DTD,但如果文件的格式不完整,它將會隨著出錯資訊而停止。
提供事件處理函數來處理文件
建立自己的事件結構例如堆疊和樹來獲得XML結構資訊標記的優點。
每天都有新的XML程式出現,而PHP對XML的支援也不斷加強(例如,增加了支援基於DOM的XML解析器LibXML)。
有了PHP和Expat,你就可以為即將出現的有效、開放和獨立於平台的標準做好準備。

目前1/2頁 12下一頁

以上就介紹了export_symbol php xml分析函數程式碼第1/2頁,包含了export_symbol方面的內容,希望對PHP教學有興趣的朋友有幫助。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn