国产午夜成人免费看片无遮挡_日本免费xxxx色视频_免费人成网上在线观看_黄网址在线永久免费观看

當前位置:雨林木風下載站 > 技術開發教程 > 詳細頁面

PHP的XML區分函數(轉) (介紹這個PHP里的XML區分函數的文章可不太有哦。。 看過這篇就應該清楚點了吧...

PHP的XML區分函數(轉) (介紹這個PHP里的XML區分函數的文章可不太有哦。。 看過這篇就應該清楚點了吧...

更新時間:2022-05-08 文章作者:未知 信息來源:網絡 閱讀次數:

PHP的XML分析函數

首先我得承認我喜歡計算機標準。如果每個人都遵從這個行業的標準,互聯網將會是一個更好的媒體。使用標準化的數據交換格式才能使開放的和獨立于平臺的計算模式切實可行。這就是我作為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文檔范例:

<greeting>
Hello World
</greeting>

基于事件的解析器將報告為三個事件:

開始元素: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_processing_instruction_handler() 處理指令的出現

記法聲明 xml_set_notation_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的重要特性。例如,元素序列<book><title>表示的意思不同于<figure><title>。也就是說,任何作者都會告訴你書名和圖名是沒有關系的,雖然它們都用到"title"這個術語。因此,為了更有效地使用基于事件的解析器處理XML,你必須使用自己的棧(stacks)或列表(lists)來維護文檔的結構信息。


為了產生文檔結構的鏡像,腳本至少需要知道目前元素的父元素。用Exapt的API是無法實現的,它只報告目前元素的事件,而沒有任何前后關系的信息。因此,你需要建立自己的棧結構。


腳本范例使用先進后出(FILO)的棧結構。通過一個數組,棧將保存全部的開始元素。對于開始元素處理函數,目前的元素將被array_push()函數推到棧的頂部。相應的,結束元素處理函數通過array_pop()將最頂的元素移走。


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

開始元素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,你就可以為即將出現的有效、開放和獨立于平臺的標準作準備。

范例

<?
/*****************************************************************************
* 名稱:XML解析范例:XML文檔信息統計
* 描述
* 本范例通過PHP的Expat解析器收集和統計XML文檔的信息(例如:每個元素出現的次數、父元素和子元素
* XML文件作為一個參數 ./xmlstats_PHP4.php3 test.xml
* $Requires: Expat 要求:Expat PHP4.0編譯為CGI模式
*****************************************************************************/

// 第一個參數是XML文件
$file = $argv[1];

// 變量的初始化
$elements = $stack = array();
$total_elements = $total_chars = 0;

// 元素的基本類
class element
{
var $count = 0;
var $chars = 0;
var $parents = array();
var $childs = array();
}

// 解析XML文件的函數
function xml_parse_from_file($parser, $file)
{
if(!file_exists($file))
{
die("Can't find file \"$file\".");
}

if(!($fp = @fopen($file, "r")))
{
die("Can't open file \"$file\".");
}

while($data = fread($fp, 4096))
{
if(!xml_parse($parser, $data, feof($fp)))
{
return(false);
}
}

fclose($fp);

return(true);
}

// 輸出結果函數(方框形式)
function print_box($title, $value)
{
printf("\n+%'-60s+\n", "");
printf("|%20s", "$title:");
printf("%14s", $value);
printf("%26s|\n", "");
printf("+%'-60s+\n", "");
}

// 輸出結果函數(行形式)
function print_line($title, $value)
{
printf("%20s", "$title:");
printf("%15s\n", $value);
}

// 排序函數
function my_sort($a, $b)
{
return(is_object($a) && is_object($b) ? $b->count - $a->count: 0);
}

function start_element($parser, $name, $attrs)
{
global $elements, $stack;

// 元素是否已在全局$elements數組中?
if(!isset($elements[$name]))
{
// 否-增加一個元素的類實例
$element = new element;
$elements[$name] = $element;
}

// 該元素的記數器加一
$elements[$name]->count++;

// 是否有父元素?
if(isset($stack[count($stack)-1]))
{
// 是-將父元素賦給$last_element
$last_element = $stack[count($stack)-1];

// 如果目前元素的父元素數組為空,初始化為0
if(!isset($elements[$name]->parents[$last_element]))
{
$elements[$name]->parents[$last_element] = 0;
}

// 該元素的父元素記數器加一
$elements[$name]->parents[$last_element]++;

// 如果目前元素的父元素的子元素數組為空,初始化為0

if(!isset($elements[$last_element]->childs[$name]))
{
$elements[$last_element]->childs[$name] = 0;
}

// 該元素的父元素的子元素記數器加一
$elements[$last_element]->childs[$name]++;
}

// 將目前的元素加入到棧中
array_push($stack, $name);
}

function stop_element($parser, $name)
{
global $stack;

// 從棧中將最頂部的元素移去
array_pop($stack);
}

function char_data($parser, $data)
{
global $elements, $stack, $depth;

// 增加目前元素的字符數目
$elements[$stack][count($stack)-1]]->chars += strlen(trim($data));
}

// 產生解析器的實例
$parser = xml_parser_create();

// 設置處理函數
xml_set_element_handler($parser, "start_element", "stop_element");
xml_set_character_data_handler($parser, "char_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);

// 釋放協助元素
unset($elements["current_element"]);
unset($elements["last_element"]);

// 根據元素的次數排序
uasort($elements, "my_sort");

// 在$elements中循環收集元素信息
while(list($name, $element) = each($elements))
{
print_box("Element name", $name);

print_line("Element count", $element->count);
print_line("Character count", $element->chars);

printf("\n%20s\n", "* Parent elements");

// 在該元素的父中循環,輸出結果
while(list($key, $value) = each($element->parents))
{
print_line($key, $value);
}
if(count($element->parents) == 0)
{
printf("%35s\n", "[root element]");
}

// 在該元素的子中循環,輸出結果
printf("\n%20s\n", "* Child elements");
while(list($key, $value) = each($element->childs))
{
print_line($key, $value);
}
if(count($element->childs) == 0)
{
printf("%35s\n", "[no childs]");
}

$total_elements += $element->count;
$total_chars += $element->chars;
}

// 最終結果
print_box("Total elements", $total_elements);
print_box("Total characters", $total_chars);
?> 

溫馨提示:喜歡本站的話,請收藏一下本站!

本類教程下載

系統下載排行

国产午夜成人免费看片无遮挡_日本免费xxxx色视频_免费人成网上在线观看_黄网址在线永久免费观看

  • <label id="pxtpz"><meter id="pxtpz"></meter></label>
      1. <span id="pxtpz"><optgroup id="pxtpz"></optgroup></span>

        欧美日韩精品一二三区| 国产成人精品在线看| 国产在线精品国自产拍免费| 欧美精品tushy高清| 日日夜夜精品视频免费| 日韩精品专区在线影院重磅| 国产在线观看一区二区| 国产日韩精品一区二区浪潮av| 国产一区二区三区av电影| 国产精品久久久久久久久搜平片 | 日韩一区二区三区在线| 国产在线精品一区在线观看麻豆| 国产日本一区二区| 欧美三级中文字幕| 国产一区二区在线免费观看| 亚洲视频免费看| 日韩一区二区在线观看视频| 国产激情视频一区二区在线观看| 亚洲少妇30p| 欧美成人免费网站| 色狠狠桃花综合| 国产一区二区精品久久| 亚洲香肠在线观看| 国产欧美一区二区三区在线老狼| 在线亚洲一区二区| 国产一区二区三区蝌蚪| 亚洲国产乱码最新视频 | 亚洲欧洲成人av每日更新| 欧美日韩一级片网站| 国产精品资源在线看| 午夜视频久久久久久| 国产精品三级久久久久三级| 欧美一区二区三区播放老司机| 不卡电影一区二区三区| 精品在线一区二区| 香蕉加勒比综合久久| 国产精品久久夜| 久久先锋资源网| 91精品欧美一区二区三区综合在| 91色视频在线| 成人性色生活片免费看爆迷你毛片| 免费看日韩a级影片| 亚洲午夜久久久久久久久电影网| 国产欧美日韩在线观看| 欧美电影免费观看完整版| 欧美日韩国产另类一区| 在线观看日韩高清av| 91视视频在线直接观看在线看网页在线看| 精品亚洲免费视频| 裸体一区二区三区| 青青草国产成人av片免费| 亚洲妇熟xx妇色黄| 亚洲第一狼人社区| 亚洲综合小说图片| 一区二区三区小说| 亚洲一区在线看| 亚洲成在线观看| 日本欧美韩国一区三区| 日韩国产一区二| 蜜臀av一区二区三区| 久久精品国产成人一区二区三区| 麻豆免费看一区二区三区| 青青草91视频| 激情都市一区二区| 国产伦精品一区二区三区视频青涩 | 欧美特级限制片免费在线观看| 99视频精品免费视频| 91视频免费观看| 欧美怡红院视频| 欧美高清视频不卡网| 日韩午夜激情电影| 久久久午夜精品理论片中文字幕| 久久日一线二线三线suv| 国产日韩三级在线| 亚洲男人天堂一区| 亚洲综合色婷婷| 日本三级亚洲精品| 国产一区三区三区| 99精品国产视频| 欧美喷潮久久久xxxxx| 精品国产一区二区三区不卡 | 欧美中文字幕不卡| 日韩亚洲欧美一区二区三区| 精品国产免费视频| 成人免费小视频| 日韩国产在线一| 国产精品主播直播| 欧美三级中文字幕在线观看| 欧美电影免费观看完整版| 国产精品久久毛片| 午夜在线电影亚洲一区| 国产精品99久久久久久久女警| 91麻豆国产在线观看| 日韩一区二区三区在线| 自拍视频在线观看一区二区| 日韩精品1区2区3区| av电影在线观看一区| 日韩欧美国产高清| 亚洲乱码国产乱码精品精的特点| 日韩精品久久理论片| 成人av电影在线观看| 欧美一区二区三区电影| 亚洲理论在线观看| 国产盗摄一区二区三区| 欧美视频日韩视频| ww亚洲ww在线观看国产| 天堂在线亚洲视频| 91小视频在线观看| 久久久久久久性| 免费av网站大全久久| 欧美在线一区二区| 中文字幕一区二区三区不卡在线 | 亚洲影院理伦片| 99在线热播精品免费| 国产亚洲一区二区在线观看| 蜜臀av性久久久久蜜臀av麻豆| 91看片淫黄大片一级在线观看| 精品久久久久久久久久久院品网 | 亚洲免费观看高清完整版在线| 精一区二区三区| 日韩一级二级三级| 免费高清在线视频一区·| 欧美三级资源在线| 亚洲三级视频在线观看| 波多野结衣在线一区| 国产校园另类小说区| 久久精品国产一区二区| 日韩片之四级片| 日本大胆欧美人术艺术动态| 欧美日韩国产美| 日韩国产欧美视频| 91精品国产福利| 午夜精彩视频在线观看不卡| 91视频你懂的| 亚洲精品国产精华液| 色先锋资源久久综合| 亚洲免费高清视频在线| 97国产一区二区| 一区二区三区欧美在线观看| 97精品久久久久中文字幕| 一区二区在线电影| 日本高清不卡aⅴ免费网站| 亚洲男人的天堂在线观看| 在线观看日韩av先锋影音电影院| 亚洲人成人一区二区在线观看| 91在线小视频| 香蕉成人啪国产精品视频综合网| 欧美情侣在线播放| 韩国午夜理伦三级不卡影院| 国产亚洲人成网站| 成人av网站在线观看免费| 亚洲精品国产精华液| 欧美一区二区精品久久911| 精品一二线国产| 中文字幕一区在线观看视频| 91久久久免费一区二区| 奇米777欧美一区二区| 国产三级精品在线| 在线观看91视频| 久久91精品国产91久久小草| 国产精品嫩草久久久久| 欧美少妇一区二区| 激情亚洲综合在线| 亚洲欧美国产高清| 欧美成va人片在线观看| 波多野结衣中文字幕一区| 日韩中文字幕区一区有砖一区| 久久色中文字幕| 欧美专区亚洲专区| 国产伦精一区二区三区| 亚洲一区二区高清| 久久免费视频色| 欧美美女一区二区在线观看| 风流少妇一区二区| 日本三级韩国三级欧美三级| 中文字幕在线观看不卡视频| 日韩一区二区三区精品视频| 成年人国产精品| 精品亚洲免费视频| 亚洲国产一区在线观看| 久久众筹精品私拍模特| 91成人在线观看喷潮| 风间由美一区二区三区在线观看 | 男女男精品视频网| 亚洲欧美日韩久久精品| 久久嫩草精品久久久精品一| 欧美高清视频不卡网| 色婷婷综合在线| 成人动漫在线一区| 国产一区二区精品久久| 蜜桃视频一区二区三区| 亚洲制服丝袜av| 亚洲欧美在线高清| 欧美高清在线精品一区| 亚洲精品一区在线观看| 日韩欧美国产麻豆| 日韩一区二区三区免费观看| 欧美性受极品xxxx喷水| 色噜噜狠狠色综合欧洲selulu| 成人avav在线|