亚洲韩日午夜视频,欧美日韩在线精品一区二区三区,韩国超清无码一区二区三区,亚洲国产成人影院播放,久草新在线,在线看片AV色

您好,歡迎來到思海網(wǎng)絡(luò),我們將竭誠(chéng)為您提供優(yōu)質(zhì)的服務(wù)! 誠(chéng)征網(wǎng)絡(luò)推廣 | 網(wǎng)站備案 | 幫助中心 | 軟件下載 | 購買流程 | 付款方式 | 聯(lián)系我們 [ 會(huì)員登錄/注冊(cè) ]
促銷推廣
客服中心
業(yè)務(wù)咨詢
有事點(diǎn)擊這里…  531199185
有事點(diǎn)擊這里…  61352289
點(diǎn)擊這里給我發(fā)消息  81721488
有事點(diǎn)擊這里…  376585780
有事點(diǎn)擊這里…  872642803
有事點(diǎn)擊這里…  459248018
有事點(diǎn)擊這里…  61352288
有事點(diǎn)擊這里…  380791050
技術(shù)支持
有事點(diǎn)擊這里…  714236853
有事點(diǎn)擊這里…  719304487
有事點(diǎn)擊這里…  1208894568
有事點(diǎn)擊這里…  61352289
在線客服
有事點(diǎn)擊這里…  531199185
有事點(diǎn)擊這里…  61352288
有事點(diǎn)擊這里…  983054746
有事點(diǎn)擊這里…  893984210
當(dāng)前位置:首頁 >> 技術(shù)文章 >> 文章瀏覽
技術(shù)文章

PHP中的XML應(yīng)用

添加時(shí)間:2014-7-28 1:19:07  添加: 思海網(wǎng)絡(luò) 
 綜述

  XML代表Extensible Markup Language(eXtensible Markup Language的縮寫,意為可擴(kuò)展的標(biāo)記語言)。XML是一套定義語義標(biāo)記的規(guī)則,這些標(biāo)記將文檔分成許多部件并對(duì)這些部件加以標(biāo)識(shí)。它也是元標(biāo)記語言,即定義了用于定義其他與特定領(lǐng)域有關(guān)的、語義的、結(jié)構(gòu)化的標(biāo)記語言的句法語言。XML是當(dāng)今最熱門的技術(shù)。而PHP也具有分析XML文檔的功能,下面我們將共同探討一下PHP中的XML應(yīng)用的情況。

  XML概貌

  談起XML(eXtended Markup Language:可擴(kuò)展標(biāo)記語言),我們不妨先看一段HTML的代碼:

  <html> 
  <title>XML</title> 
  <body> 
  <p><center><font color="red">TEXT</font></center></p> 
  <a href="www.domain.com"><img src="http://edu.cnzz.cn/NewsInfo/logo.jpg"/></a> 
  </body> 
  </html> 

  上面這段代碼從結(jié)構(gòu)上就符合XML的規(guī)則,XML可以理解是包含數(shù)據(jù)的樹形的結(jié)構(gòu)類型:

  1、引用同一個(gè)元素的時(shí)候,使用一致的大小寫,如<center></Center>就是不符合規(guī)定的 
  2、任何屬性值(如 href="????")要用""引起來,如<a href=www.yahoo.com>就是不正確的
  3、所有元素必須由打開<和關(guān)閉>標(biāo)注組成,元素應(yīng)該形如<body></body>或空元素<img ... />,如果結(jié)尾的 "/>" 少了"/"就是錯(cuò)誤的代碼 
  4、所有元素必須彼此嵌套,就像寫程序的循環(huán)一樣,而且,所有的元素必須嵌套于根元素之中,比如上面的代碼所有的內(nèi)容都嵌套于<html></html>之中。 
  5、元素名稱(即上面的body a p img等)應(yīng)為字母開頭。

  怎樣應(yīng)用PHP的XML解析器Expat?

  Expat是PHP腳本語言的XML解析器(同樣稱為XML處理器),可以使程序訪問XML文檔的結(jié)構(gòu)和內(nèi)容。它是一種基于事件的解析器。XML解析器有兩種基本類型:

  基于樹型的解析器:將XML文檔轉(zhuǎn)換成樹型結(jié)構(gòu)。這類解析器分析整篇文章,同時(shí)提供一個(gè)API來訪問所產(chǎn)生樹的每個(gè)元素。其通用的標(biāo)準(zhǔn)為DOM(文檔對(duì)象模式)。

  基于事件的解析器:將XML文檔視為一系列的事件。當(dāng)一個(gè)特殊事件發(fā)生時(shí),解析器將調(diào)用開發(fā)者提供的函數(shù)來處理。基于事件的解析器有一個(gè)XML文檔的數(shù)據(jù)集中視圖,也就是說它集中在XML文檔的數(shù)據(jù)部分,而不是其結(jié)構(gòu)。這些解析器從頭到尾處理文檔,并將類似于-元素的開始、元素的結(jié)尾、特征數(shù)據(jù)的開始等等-事件通過回調(diào)(callback)函數(shù)報(bào)告給應(yīng)用程序。

  以下是一個(gè)"Hello-World"的XML文檔范例:

<greeting> 
Hello World 
</greeting> 

  基于事件的解析器將報(bào)告為三個(gè)事件:

  開始元素:greeting 
  CDATA項(xiàng)的開始,值為:Hello World 
  結(jié)束元素:greeting

  基于事件的解析器不產(chǎn)生描述文檔的結(jié)構(gòu),當(dāng)然如果使用Expat,必要時(shí)它一樣可以在PHP中生成完全的原生樹結(jié)構(gòu)。在CDATA項(xiàng)中,基于事件的解析器不會(huì)得到父元素greeting的信息。然而,它提供一個(gè)更底層的訪問,這就使得可以更好地利用資源和更快地訪問。通過這種方式,就沒有必要將整個(gè)文檔放入內(nèi)存;而事實(shí)上,整個(gè)文檔甚至可以大于實(shí)際內(nèi)存值。

  上面Hello-World的范例雖然包括完整的XML格式,但它是無效的,因?yàn)榧葲]有DTD(文檔類型定義)與其聯(lián)系,也沒有內(nèi)嵌DTD。但是Expat是一個(gè)不檢查有效性的解析器,因此忽略任何與文檔聯(lián)系的DTD。應(yīng)注意的是文檔仍然需要完整的格式,否則Expat(和其他符合XML標(biāo)準(zhǔn)的解析器一樣)將會(huì)隨著出錯(cuò)信息而停止。

  編譯Expat

  Expat可以編譯進(jìn)PHP3.0.6版本(或以上)中。從Apache1.3.22開始,Expat已經(jīng)作為Apache的一部分。在Unix系統(tǒng)中,可以通過-with-xml選項(xiàng)配置PHP將其編譯入PHP。

  如果將PHP編譯為Apache的模塊,而Expat將默認(rèn)作為Apache的一部分。在Windows中,則必須要加載XML動(dòng)態(tài)連接庫。

  XML范例:XMLstats 
  我們所要討論的范例是使用Expat來收集XML文檔的統(tǒng)計(jì)數(shù)據(jù)。

  對(duì)于文檔中每個(gè)元素,以下信息都將被輸出: 
該元素在文檔中使用的次數(shù) 
該元素中字符數(shù)據(jù)的數(shù)量

元素的父元素

元素的子元素 
  注意:為了演示,我們利用PHP來產(chǎn)生一個(gè)結(jié)構(gòu)來保存元素的父元素和子元素


 用于產(chǎn)生XML解析器實(shí)例的函數(shù)有哪些?

  用于產(chǎn)生XML解析器實(shí)例的函數(shù)為xml_parser_create()。該實(shí)例將用于以后的所有函數(shù)。這個(gè)思路非常類似于PHP中MySQL函數(shù)的連接標(biāo)記。在解析文檔前,基于事件的解析器通常要求注冊(cè)回調(diào)函數(shù)-用于特定的事件發(fā)生時(shí)調(diào)用。Expat沒有例外事件,它定義了如下七個(gè)可能事件:

對(duì)象 XML解析函數(shù) 描述 
元素 xml_set_element_handler() 元素的開始和結(jié)束 
字符數(shù)據(jù) xml_set_character_data_handler() 字符數(shù)據(jù)的開始 
外部實(shí)體 xml_set_external_entity_ref_handler() 外部實(shí)體出現(xiàn)  
未解析外部實(shí)體 xml_set_unparsed_entity_decl_handler() 未解析的外部實(shí)體出現(xiàn) 
處理指令 xml_set_processing_instruction_handler() 處理指令的出現(xiàn) 
記法聲明 xml_set_notation_decl_handler() 記法聲明的出現(xiàn) 
默認(rèn) xml_set_default_handler() 其它沒有指定處理函數(shù)的事件

  所有的回調(diào)函數(shù)必須將解析器的實(shí)例作為其第一個(gè)參數(shù)(此外還有其它參數(shù))。

  對(duì)于本文最后的范例腳本,需要注意的是它既用到了元素處理函數(shù)又用到了字符數(shù)據(jù)處理函數(shù)。元素的回調(diào)處理函數(shù)通過xml_set_element_handler()來注冊(cè)。

  這個(gè)函數(shù)需要三個(gè)參數(shù):

  解析器的實(shí)例 
  處理開始元素的回調(diào)函數(shù)的名稱 
  處理結(jié)束元素的回調(diào)函數(shù)的名稱

  當(dāng)開始解析XML文檔時(shí),回調(diào)函數(shù)必須存在。它們必須定義為與PHP手冊(cè)中所描述的原型一致。

  例如,Expat將三個(gè)參數(shù)傳遞給開始元素的處理函數(shù)。在腳本范例中,其定義如下:

  function start_element($parser, $name, $attrs)

  $parser是解析器標(biāo)志,$name是開始元素的名稱,$attrs為包含元素所有屬性和值的數(shù)組。

  一旦開始解析XML文檔,Expat在遇到開始元素是都將調(diào)用start_element()函數(shù)并將參數(shù)傳遞過去。

  XML的Case Folding選項(xiàng)

  用xml_parser_set_option()函數(shù)將Case folding選項(xiàng)關(guān)閉。這個(gè)選項(xiàng)默認(rèn)是打開的,使得傳遞給處理函數(shù)的元素名自動(dòng)轉(zhuǎn)換為大寫。但XML對(duì)大小寫是敏感的(所以大小寫對(duì)統(tǒng)計(jì)XML文檔是非常重要的)。對(duì)于我們的范例,case folding選項(xiàng)必須關(guān)閉。

  如何對(duì)文檔進(jìn)行解析?

  在完成所有的準(zhǔn)備工作后,現(xiàn)在腳本終于可以解析XML文檔:

  Xml_parse_from_file(),一個(gè)自定義的函數(shù),打開參數(shù)中指定的文件,并以4kb的大小進(jìn)行解析 
xml_parse(),和xml_parse_from_file()一樣,當(dāng)發(fā)生錯(cuò)誤時(shí),即XML文檔的格式不完全時(shí),將會(huì)返回false。

  我們可以使用xml_get_error_code()函數(shù)來得到最后一個(gè)錯(cuò)誤的數(shù)字代碼。將此數(shù)字代碼傳遞給xml_error_string()函數(shù)即可得到錯(cuò)誤的文本信息。輸出XML當(dāng)前的行數(shù),使得調(diào)試更容易。

  當(dāng)解析文檔時(shí),對(duì)于Expat需要強(qiáng)調(diào)問題的是:如何保持文檔結(jié)構(gòu)的基本描述?

  如前所述,基于事件的解析器本身并不產(chǎn)生任何結(jié)構(gòu)信息。不過標(biāo)簽(tag)結(jié)構(gòu)是XML的重要特性。例如,元素序列<book><title>表示的意思不同于<figure><title>。書名和圖名是沒有關(guān)系的,雖然它們都用到"title"這個(gè)術(shù)語。因此,為了更有效地使用基于事件的解析器處理XML,必須使用自己的棧(stacks)或列表(lists)來維護(hù)文檔的結(jié)構(gòu)信息。

  為了產(chǎn)生文檔結(jié)構(gòu)的鏡像,腳本至少需要知道目前元素的父元素。用Exapt的API是無法實(shí)現(xiàn)的,它只報(bào)告目前元素的事件,而沒有任何前后關(guān)系的信息。因此,需要建立自己的棧結(jié)構(gòu)。

  腳本范例使用先進(jìn)后出(FILO)的棧結(jié)構(gòu)。通過一個(gè)數(shù)組,棧將保存全部的開始元素。對(duì)于開始元素處理函數(shù),目前的元素將被array_push()函數(shù)推到棧的頂部。相應(yīng)的,結(jié)束元素處理函數(shù)通過array_pop()將最頂?shù)脑匾谱摺?/p>

  對(duì)于序列<book><title></title></book>,棧的填充如下:

  開始元素book:將"book"賦給棧的第一個(gè)元素($stack[0])。 
  開始元素title:將"title"賦給棧的頂部($stack[1])。 
  結(jié)束元素title:從棧中將最頂部的元素移去($stack[1])。 
  結(jié)束元素title:從棧中將最頂部的元素移去($stack[0])。

  PHP3.0通過一個(gè)$depth變量手動(dòng)控制元素的嵌套來實(shí)現(xiàn)范例,這就使腳本看起來比較復(fù)雜。PHP4.0通過array_pop()和array_push()兩個(gè)函數(shù)來使腳本看起來更簡(jiǎn)潔。

  如何收集XML文檔中的元素信息?

  為了收集每個(gè)元素的信息,腳本需要記住每個(gè)元素的事件。通過使用一個(gè)全局的數(shù)組變量$elements來保存文檔中所有不同的元素。數(shù)組的項(xiàng)目是元素類的實(shí)例,有4個(gè)屬性(類的變量)

  $count -該元素在文檔中被發(fā)現(xiàn)的次數(shù) 
  $chars -元素中字符事件的字節(jié)數(shù) 
  $parents -父元素 
  $childs - 子元素

  注意:PHP的一個(gè)特性是你可以通過while(list() = each())loop遍歷整個(gè)類結(jié)構(gòu),如同你遍歷整個(gè)相應(yīng)的數(shù)組一樣。所有的類變量(當(dāng)你用PHP3.0時(shí)還有方法名)都以字符串的方式輸出。

  當(dāng)發(fā)現(xiàn)一個(gè)元素時(shí),我們需要增加其相應(yīng)的記數(shù)器來跟蹤它在文檔中出現(xiàn)多少次。在相應(yīng)的$elements項(xiàng)中的記數(shù)元素也要加一。

  我們同樣要讓父元素知道目前的元素是它的子元素。因此,目前元素的名稱將會(huì)加入到父元素的$childs數(shù)組的項(xiàng)目中。最后,目前元素應(yīng)該記住誰是它的父元素。所以,父元素被加入到目前元素$parents數(shù)組的項(xiàng)目中。

  顯示統(tǒng)計(jì)信息

  剩下的代碼在$elements數(shù)組和其子數(shù)組中循環(huán)顯示其統(tǒng)計(jì)結(jié)果。這就是最簡(jiǎn)單的嵌套循環(huán),盡管輸出正確的結(jié)果,但代碼既不簡(jiǎn)潔又沒有任何特別的技巧,它僅僅是一個(gè)你可能每天用他來完成工作的循環(huán)。


 腳本范例被設(shè)計(jì)為通過PHP的CGI方式的命令行來調(diào)用。因此,統(tǒng)計(jì)結(jié)果輸出的格式為文本格式。如果你要將腳本運(yùn)用到互聯(lián)網(wǎng)上,那么你需要修改輸出函數(shù)來產(chǎn)生HTML格式。

  如何用PHP&XML編制一個(gè)迷你搜索引擎實(shí)例?

  讓我們首先來熟悉一下我們程序中用到的那個(gè)XML(保存為xyz.xml)。

<?xml version="1.0" encoding="gb2312" ?>
<links>采用PHP和XML技術(shù)構(gòu)建的搜索引擎 
<web memo="memo1" url="">name1</web> 
<sub>電腦網(wǎng)絡(luò) 
<web memo="nemo2">name2</web> 
<sub>程序設(shè)計(jì) 
<web memo="memo3">name3</web> 
<sub>PHP 
<web url="http://www.phpbuilder.com/" memo="[英文]PHP開發(fā)資源。"> 
www.phpbuilder.com</web> 
<web url="http://www.fokus.gmd.de" memo="[英文]PHP開發(fā)手冊(cè)。 "> 
PHP Manual</web> 
</sub> 
</sub> 
</sub> 
</links>

  它的結(jié)構(gòu)相當(dāng)簡(jiǎn)單,根元素就是links,sub代表著一個(gè)類別,web就是一個(gè)網(wǎng)站的信息,其中包含著屬性,url代表網(wǎng)站的聯(lián)接,memo為備注信息,<web>??</web> 、<sub>??</sub>中包含的為元素的數(shù)據(jù)在這里就是類別和網(wǎng)站的名稱,這是符合上面的規(guī)定的。

  現(xiàn)在我們來回答上面提出的問題:為什么要用XML來編制搜索引擎?
  第一個(gè)原因就是有時(shí)候由于各種原因我們可能不能用到數(shù)據(jù)庫(MySQL或者其他);
  其次,對(duì)于小數(shù)據(jù)量的搜索引擎來說,它的數(shù)據(jù)量很小,如果用數(shù)據(jù)庫來做,效率未必有多高;

  最重要的一點(diǎn)是,這個(gè)搜索引擎維護(hù)起來相當(dāng)?shù)暮?jiǎn)單,并且不用編寫繁瑣的數(shù)據(jù)庫的維護(hù)的程序。例如,我們要添加一個(gè)類別或者網(wǎng)頁,只要編輯文本的文件,加上一福紈eb>???</web>或是<sub>????</sub>就可以了,而且,如果想把一個(gè)類別移動(dòng)到另一個(gè)地方的話,我們只要將這一部分的sub復(fù)制過去就行了。

  下面一個(gè)最簡(jiǎn)單的用PHP顯示XML的范例。

  下面的程序是將解析XML并按照樹形結(jié)構(gòu)輸出至瀏覽器,并顯示每層的元素總數(shù)。

<?php
$file = "demo.xml";// XML文件
function xml_parse_from_file($parser, $file) {// 解析XML文件的函數(shù) }
function start_element($parser, $name, $attrs) {//遇到了開元素標(biāo)記如<a href="link">就執(zhí)行這一段}
function stop_element($parser, $name) {//遇到了開元素標(biāo)記如</body>就執(zhí)行這一段}
function data($parser, $data) {……}
function showcount(){ //顯示每一層的元素總數(shù)}

global $level,$levelcount,$maxlevel; 
$level = -1; 
$parser = xml_parser_create();// 產(chǎn)生解析器的實(shí)例 
xml_set_element_handler($parser, "start_element", "stop_element"); // 設(shè)置處理函數(shù) 
xml_set_character_data_handler($parser, "data"); 
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); 
$ret = xml_parse_from_file($parser, $file); // 解析文件 
if(!$ret) { 
die(sprintf("XML error: %s at line %d", xml_error_string(xml_get_error_code($parser)), xml_get_current_line_number($parser))); 

xml_parser_free($parser); // 釋放解析器 
showcount();
?> 

  在上面的程序的基礎(chǔ)上,可以顯示一段子樹,我們依照元素的層數(shù)和他在該層的第幾號(hào)來對(duì)他進(jìn)行定位

  例如:

    links (0,1) 
    +----web (1,1) 
    +----sub (1,2) 
    | +----web (2,1) 
    | +----sub (2,2) 
    | | +----web (3,1) 
    | | +----sub (3,2) 
    : 
    : 
    : 

  下面的代碼是我們的搜索引擎的基礎(chǔ)。因?yàn)椋@示出一個(gè)子類別(如程序設(shè)計(jì)->PHP->)的信息就要用到他。

<?php
……
function start_element($parser, $name, $attrs) { 
global $level,$levelcount,$maxlevel,$hide,$lev,$num,$PHP_SELF; 
$level += 1; 
if($level>$maxlevel)
$maxlevel=$level; 
$levelcount[$level]+=1;

if($hide){ //判斷是否在子樹的范圍內(nèi),$hide==FALSE 為在 
if($level==$lev&&$levelcount[$level]==$num)
$hide=FALSE; 
}else{ 
if($level<=$lev)$hide=TRUE; 
}

if(!$hide){ 
……//輸出

}
function data($parser, $data) { 
global $level,$hide; 
if(!$hide){ 
if(trim($data)!=""){ echo trim($data); } 
}
}
……
global $hide,$lev,$num,$PHP_SELF; 
$level = -1; 
$hide = TRUE; 
echo "<p><a href=$PHP_SELF>Root</a></p>"; 
if($lev==""){
$lev=0;$num=1;
}
……
?>

  mini的搜索引擎到底如何做呢?

  作了若干的鋪墊,下面我們就來看一下我們的搜索引擎的主要文件。

  第一段為仿sina,yahoo的按照類別查詢 
  第二段為搜索查詢部分(把整個(gè)樹遍歷一遍)顯示符合的內(nèi)容。

  xml3.php

  關(guān)鍵字匹配采用eregi函數(shù),我們假設(shè)輸入的文字都是不會(huì)導(dǎo)致錯(cuò)誤的。

關(guān)鍵字:PHP、XML、規(guī)則

分享到:

頂部 】 【 關(guān)閉
版權(quán)所有:佛山思海電腦網(wǎng)絡(luò)有限公司 ©1998-2024 All Rights Reserved.
聯(lián)系電話:(0757)22630313、22633833
中華人民共和國(guó)增值電信業(yè)務(wù)經(jīng)營(yíng)許可證: 粵B1.B2-20030321 備案號(hào):粵B2-20030321-1
網(wǎng)站公安備案編號(hào):44060602000007 交互式欄目專項(xiàng)備案編號(hào):200303DD003  
察察 工商 網(wǎng)安 舉報(bào)有獎(jiǎng)  警警  手機(jī)打開網(wǎng)站