真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

PHP中的SimpleXML處理-創(chuàng)新互聯(lián)

PHP 版本 5 引入了 SimpleXML,一種用于讀寫(xiě) XML 的新的應(yīng)用程序編程接口(API)。在 SimpleXML 中,下面的這樣的表達(dá)式:PHP中的SimpleXML處理
$doc->rss->channel->item->title

從文檔中選擇元素。只要熟悉文檔的結(jié)構(gòu),很容易編寫(xiě)這種表達(dá)式。但是,如果不很清楚需要的元素出現(xiàn)在何處(比如 Docbook、HTML 和類似的敘述性文檔中),SimpleXML 可以使用 XPath 表達(dá)式尋找這些元素。

在博山等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站制作、做網(wǎng)站 網(wǎng)站設(shè)計(jì)制作按需設(shè)計(jì),公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站設(shè)計(jì),營(yíng)銷型網(wǎng)站建設(shè),外貿(mào)網(wǎng)站建設(shè),博山網(wǎng)站建設(shè)費(fèi)用合理。

開(kāi)始使用 SimpleXML

假設(shè)需要一個(gè) PHP 頁(yè)面將 RSS 提要(feed)轉(zhuǎn)化成 HTML。RSS 是一種簡(jiǎn)單的 XML 格式用于發(fā)布連鎖內(nèi)容。文檔的根元素是rss,它包括一個(gè) channel 元素。channel 元素包含關(guān)于提要的元數(shù)據(jù),如標(biāo)題、語(yǔ)言和 URL。它還包含各種封裝在 item 元素中的報(bào)道。每個(gè) item 都有一個(gè) link 元素,包括一個(gè) URL,還有 title 或 description(通常兩者都有),包含普通文本。不使用名稱空間。RSS 的內(nèi)容當(dāng)然不止這些,不過(guò)對(duì)本文來(lái)說(shuō)知道這些就足夠了。清單 1 顯示了一個(gè)典型的例子,它包含兩個(gè)新聞項(xiàng)。

清單 1. RSS 提要

Mokka mit Schlag http://www.elharo.com/blog en Penn Station: Gone but not Forgotten The old Penn Station in New York was torn down before I was born. Looking at these pictures, that feels like a mistake. The current site is functional, but no more; really just some office towers and underground corridors of no particular interest or beauty. The new Madison Square... http://www.elharo.com/blog/new-york/2006/07/31/penn-station Personal for Elliotte Harold Some people use very obnoxious spam filters that require you to type some random string in your subject such as E37T to get through. Needless to say neither I nor most other people bother to communicate with these paranoids. They are grossly overreacting to the spam problem. Personally I won't ... http://www.elharo.com/blog/tech/2006/07/28/personal-for-elliotte-harold/

我們來(lái)開(kāi)發(fā)一個(gè) PHP 頁(yè)面將 RSS 提要格式化為 HTML。清單 2 顯示了這個(gè)頁(yè)面的基本結(jié)構(gòu)。

清單 2. PHP 代碼的靜態(tài)結(jié)構(gòu)

<?php // The title will be read from the RSS ?>

解析 XML 文檔

第一步是解析 XML 文檔并保存到變量中。只需要一行代碼,向 simplexml_load_file() 函數(shù)傳遞一個(gè) URL 即可:

$rss = simplexml_load_file('http://partners.userland.com/nytRss/nytHomepage.xml');

警告

這里選擇的方案絕不是最佳方案。實(shí)際上不應(yīng)該每次單擊頁(yè)面時(shí)都加載和解析 RSS 提要。對(duì)于該頁(yè)面的讀者來(lái)說(shuō)這樣做太慢,而且可能造成所加載 RSS 提要的拒絕服務(wù),多數(shù) RSS 都規(guī)定了適當(dāng)?shù)拿啃r(shí)大的刷新次數(shù)。真正的解決方案應(yīng)該緩沖生成的 HTML 頁(yè)面、RSS 提要或兩者。但是,我們重點(diǎn)是使用 SimpleXML 庫(kù),因此這里沒(méi)有過(guò)多考慮。

對(duì)于這個(gè)例子,我已經(jīng)從 Userland 的 New York Times 提要(在 http://partners.userland.com/nytRss/nytHomepage.xml)填充了頁(yè)面。當(dāng)然,也可使用其他 RSS 提要的任何 URL。

要注意,雖然名稱為 simplexml_load_file(),該函數(shù)實(shí)際上解析遠(yuǎn)程 HTTP URL 上的 XML 文檔。但這并不是該函數(shù)唯一令人感到奇怪的地方。返回值(這里存儲(chǔ)在 $rss 變量中)并沒(méi)有指向整個(gè)文檔,如果使用過(guò)其他 API 如文檔對(duì)象模型(DOM)您可能會(huì)這樣期望。相反,它指向文檔的根元素。從 SimpleXML 不能訪問(wèn)文檔序言和結(jié)語(yǔ)部分的內(nèi)容。

尋找提要標(biāo)題

整個(gè)提要的標(biāo)題(不是提要中各報(bào)道的標(biāo)題)位于 rss 根元素 channel 的 title 孩子中。很容易找到這個(gè)標(biāo)題,就仿佛 XML 文檔是類 rss 的一個(gè)對(duì)象的序列化形式,它的 channel 字段本身帶有一個(gè) title 字段。使用常規(guī) PHP 對(duì)象引用語(yǔ)法,尋找標(biāo)題的語(yǔ)句如下:

$title = $rss->channel->title;

找到之后可以將其添加到輸出 HTML 中。這樣做很簡(jiǎn)單,只要回顯 $title 變量即可:

<?php echo $title; ?>

這一行輸出元素的字符串值而不是整個(gè)元素。就是說(shuō)寫(xiě)入文本內(nèi)容但不包括標(biāo)簽。

甚至可以完全跳過(guò)中間變量 $title

<?php echo $rss->channel->title; ?>

因?yàn)樵擁?yè)面在多處重用這個(gè)值,我發(fā)現(xiàn)用一個(gè)含義明確的變量來(lái)存儲(chǔ)會(huì)更方便。

迭代新聞項(xiàng)

然后必須發(fā)現(xiàn)提要中的項(xiàng)。完成這項(xiàng)任務(wù)的表達(dá)式很簡(jiǎn)單:

$rss->channel->item

但是,提要通常包含多個(gè)新聞項(xiàng)。但也可能一個(gè)也沒(méi)有。因此,該語(yǔ)句返回一個(gè)數(shù)組,可以通過(guò) for-each 循環(huán)來(lái)遍歷它:

foreach ($rss->channel->item as $item) { echo "

" . $item->title . "

"; echo "

" . $item->description . "

"; }

通過(guò)從 RSS 提要中讀取 link 元素值添加鏈接也很容易。只要在 PHP 中輸出一個(gè) a 元素,并使用 $item->link 檢索 URL 即可。清單 3 增加了該元素并填充到 清單 1 的框架中。

清單 3. 簡(jiǎn)單而完整的 PHP RSS 閱讀器

channel->title; ?> <?php echo $title; ?>

channel->item as $item) { echo "

" . $item->title . "

"; echo "

" . $item->description . "

"; } ?>

這樣就用 PHP 完成了一個(gè)簡(jiǎn)單的 RSS 閱讀器:只需要幾行 HTML 和幾行 PHP。不算空白的話一共只有 20 行。當(dāng)然,這個(gè)實(shí)現(xiàn)的功能還不夠豐富,也不夠優(yōu)化或者健壯。我們來(lái)看看還能做什么。

 

回頁(yè)首

錯(cuò)誤處理

并非所有 RSS 提要都如期望的那樣結(jié)構(gòu)良好。XML 規(guī)范要求處理程序在發(fā)現(xiàn)結(jié)構(gòu)良好性錯(cuò)誤時(shí)停止處理文檔,SimpleXML 是符合標(biāo)準(zhǔn)的 XML 處理程序。但是在發(fā)現(xiàn)錯(cuò)誤時(shí)它沒(méi)有提供多少幫助。一般來(lái)說(shuō),它在 php-errors 文件中記錄錯(cuò)誤(但是不包括詳細(xì)的錯(cuò)誤消息),simplexml-load-file() 函數(shù)返回 FALSE。如果不能確保解析的文件是結(jié)構(gòu)良好的,在使用文件數(shù)據(jù)之前要檢查錯(cuò)誤,如清單 4 所示。

清單 4. 避免結(jié)構(gòu)錯(cuò)誤的輸入

xpath('//title') as $title) { echo "

" . $title . "

"; } } else { echo "Oops! The input is malformed!"; } ?>

其他常見(jiàn)的錯(cuò)誤是文檔實(shí)際上是結(jié)構(gòu)良好的,但是沒(méi)有在期望的地方包含期望的元素。如果項(xiàng)沒(méi)有標(biāo)題(比如在 top-100 這樣的 RSS 提要中),$doc->rss->channel->item->title 這樣的表達(dá)式會(huì)怎么樣呢?最簡(jiǎn)單的辦法是將返回值永遠(yuǎn)看作一個(gè)數(shù)組并循環(huán)遍歷該數(shù)組。這樣就可以判斷元素比預(yù)期的多還是少。但是,如果確定只需要文檔中的第一個(gè)元素 —— 即使有多個(gè),可以按索引訪問(wèn),索引號(hào)從零開(kāi)始。比如,如果要請(qǐng)求一個(gè)項(xiàng)的標(biāo)題,可以用如下代碼:

$doc->rss->channel->item[0]->title[0]

如果沒(méi)有第一項(xiàng),或者第一項(xiàng)沒(méi)有標(biāo)題,該項(xiàng)就按照常規(guī) PHP 數(shù)組索引越界處理。即結(jié)果是空,在將其插入輸出 HTML 時(shí),它會(huì)被轉(zhuǎn)化成空白字符串。

識(shí)別和拒絕不打算處理的非預(yù)期格式通常屬于 XML 驗(yàn)證解析器的范疇。然而,SimpleXML 不能針對(duì)文檔類型定義(DTD)或模式進(jìn)行驗(yàn)證。它只檢查結(jié)構(gòu)良好性。

 

回頁(yè)首

處理名稱空間

很多站點(diǎn)現(xiàn)在從 RSS 轉(zhuǎn)向了 Atom。清單 5 顯示了一個(gè) Atom 文檔的例子。該文檔大部分和 RSS 的例子類似。但是增加了一些元數(shù)據(jù),而且根元素變成了 feed 而不是 rss。feed 元素包含 entry 而不是項(xiàng)(item)。content 元素代替了 description。最重要的是,Atom 文檔使用了名稱空間,但 RSS 文檔沒(méi)有。這樣,Atom 文檔就可以在內(nèi)容中內(nèi)嵌真正的、沒(méi)有轉(zhuǎn)義的可擴(kuò)展 HTML(XHTML)。

清單 5. Atom 文檔

2006-08-04T16:00:04-04:00 http://www.cafeconleche.org/ Cafe con Leche XML News and Resources Copyright 2006 Elliotte Rusty Harold Steve Palmer has posted a beta of Vienna 2.1, an open source RSS/Atom client for Mac OS X.

Steve Palmer has posted a beta of Vienna 2.1, an open source RSS/Atom client for Mac OS X. Vienna is the first reader I've found acceptable for daily use; not great but good enough. (Of course my standards for "good enough" are pretty high.) 2.1 focuses on improving the user interface with a unified layout that lets you scroll through several articles, article filtering (e.g. read all articles since the last refresh), manual folder reordering, a new get info window, and an improved condensed layout.

http://www.cafeconleche.org/#August_1_2006_25279 2006-08-01T07:01:19Z
Matt Mullenweg has released Wordpress 2.0.4, a blog engine based on PHP and MySQL.

Matt Mullenweg has released Wordpress 2.0.4, a blog engine based on PHP and MySQL. 2.0.4 plugs various security holes, mostly involving plugins.

http://www.cafeconleche.org/#August_1_2006_21750 2006-08-01T06:02:30Z

雖然元素名稱變了,但用 SimpleXML 處理 Atom 文檔的基本方法和 RSS 相同。一個(gè)區(qū)別是現(xiàn)在請(qǐng)求被命名的元素和本地名稱時(shí)必須指定名稱空間統(tǒng)一資源標(biāo)識(shí)符(URI)。這需要兩個(gè)步驟:首先通過(guò)向 children() 函數(shù)傳遞名稱空間 URI 請(qǐng)求給定名稱空間中的孩子元素。然后用那個(gè)名稱空間中適當(dāng)?shù)谋镜孛Q請(qǐng)求元素。假設(shè)第一次把 Atom 提要加載到變量 $feed 中,如下所示:

$feed = simplexml_load_file('http://www.cafeconleche.org/today.atom');

下面的兩行尋找 title 元素:

$children = $feed->children('http://www.w3.org/2005/Atom'); $title = $children->title;

如果愿意可以將這些代碼壓縮成一行,雖然行會(huì)變得有點(diǎn)長(zhǎng)。名稱空間中的所有其他元素也必須類似處理。清單 6 給出了一個(gè)完整的 PHP 頁(yè)面,其中顯示帶名稱空間的 Atom 提要中的標(biāo)題。

清單 6. 簡(jiǎn)單的 PHP Atom 標(biāo)題閱讀器

children('http://www.w3.org/2005/Atom'); $title = $children->title; ?> <?php echo $title; ?>

entry; foreach ($entries as $entry) { $details = $entry->children('http://www.w3.org/2005/Atom'); echo "

" . $details->title . "

"; } ?>
 

回頁(yè)首

混合的內(nèi)容

為什么這個(gè)例子中只顯示標(biāo)題行呢?因?yàn)樵?Atom 中,記錄的內(nèi)容可以包含報(bào)道的全部文本:不僅僅是普通文本,還包括標(biāo)記。這是一種敘述性結(jié)構(gòu):行中的詞句是供人閱讀的。和多數(shù)的此類數(shù)據(jù)相似,也有大量的混合內(nèi)容。于是 XML 就不那么簡(jiǎn)單了,SimpleXML 方法也開(kāi)始顯示出了一些不足之處。由于不能合理地處理混合內(nèi)容,這一不足使其在很多應(yīng)用中被排除了。

可以做到一點(diǎn),但這不是一個(gè)完整的解決方案,只能用于 content 元素包含真正的 XHTML 的情況。可以使用 asXML() 函數(shù)將這些 XHTML 作為非解析源代碼直接復(fù)制到輸出中,比如:

echo "

" . $details->content->asXML() . "

";

生成的結(jié)果如清單 7 所示。

清單 7. asXML 輸出

Nikolai Grigoriev has released SVGMath 0.3, a presentation MathML formatter that produces SVG written in pure Python and published under an MIT license. According to Grigoriev, "The new version can work with multiple-namespace documents (e.g. replace all MathML subtrees with SVG in an XSL-FO or XHTML document); configuration is made more flexible, and several bugs are fixed. There is also a stylesheet to adjust the vertical position of the resulting SVG image in XSL-FO."

這不是純粹的 XHTML。content 元素悄悄從 Atom 文檔中溜了進(jìn)來(lái),您真的不愿這樣。更糟的是,它的名稱空間不對(duì),因此不能被識(shí)別。幸運(yùn)的是,這個(gè)多出來(lái)的元素實(shí)際上沒(méi)有多大害處,因?yàn)?Web 瀏覽器會(huì)忽略不認(rèn)識(shí)的任何標(biāo)簽。完成的文檔是無(wú)效的,但是關(guān)系不大。如果還是覺(jué)得別扭,可以通過(guò)字符串操作將其去掉,如下所示:

$description = $details->content->asXML(); $tags = array('", ""); $notags = array("", ""); $description = str_replace($tags, $notags, $description);

為了使代碼更加健壯,可以使用正則表達(dá)式而不是假定起始標(biāo)簽和前面相同。具體來(lái)說(shuō),可以考慮各種可能的屬性:

// end-tag is fixed in form so it's easy to replace $description = str_replace("", "", $description); // remove start-tag, possibly including attributes and white space $description = ereg_replace("]*>", "", $description);

即使這樣改進(jìn)之后,代碼還是會(huì)在注釋、處理指令和 CDATA 節(jié)上出錯(cuò)。無(wú)論怎么分解,恐怕都不會(huì)簡(jiǎn)單了。混合內(nèi)容實(shí)際上超出了 SimpleXML 所能處理的范圍。

 

回頁(yè)首

XPath

只要知道文檔有什么元素以及在什么位置,$rss->channel->item->title 這樣的表達(dá)式很方便。但是,不一定會(huì)知道得這么清楚。比方說(shuō),在 XHTML 中,標(biāo)題元素(h1、h2h3 等等)可以是 body、divtable 或其他幾種元素的孩子。此外,divtable、blockquote 及其他元素又可以互相嵌套多次。在很多不那么明確的場(chǎng)合中,使用 //h1 或 //h1[contains('Ben')]這樣的 XPath 表達(dá)式更方便。SimpleXML 通過(guò) xpath() 函數(shù)支持這種功能。

清單 8 顯示的 PHP 頁(yè)面列出了 RSS 文檔中的所有標(biāo)題,包括提要本身以及每個(gè)項(xiàng)的標(biāo)題。

清單 8. 使用 XPath 查找 title 元素

XPath Example xpath('//title') as $title) { echo "

" . $title . "

"; } ?>

SimpleXML 僅支持 XPath 位置路徑及位置路徑的組合。不支持那些不返回節(jié)點(diǎn)集的 XPath 表達(dá)式,如 count(//para) 或contains(title)。

從 PHP 5.1 版開(kāi)始,SimpleXML 可以直接對(duì)帶名稱空間的文檔使用 XPath 查詢。和通常一樣,XPath 位置路徑必須使用名稱空間前綴,即使搜索的文檔使用默認(rèn)名稱空間也仍然如此。registerXPathNamespace() 函數(shù)把前綴和后續(xù)查詢中使用的名稱空間 URL 聯(lián)系在一起。比方說(shuō),如果要查詢 Atom 文檔中的所有 title 元素,應(yīng)使用清單 9 中所示的代碼。

清單 9. 使用 XPath 和名稱空間

$atom = simplexml_load_file('http://www.cafeconleche.org/today.atom'); $atom->registerXPathNamespace('atm', 'http://www.w3.org/2005/Atom'); $titles = $atom->xpath('//atm:title'); foreach ($titles as $title) { echo "

" . $title . "

"; }

最后一點(diǎn)忠告:PHP 中的 XPath 速度非常慢。當(dāng)改為 XPath 表達(dá)式之后頁(yè)面加載延遲從難以覺(jué)察變成了幾秒鐘,即使是在負(fù)荷不高的本地服務(wù)器上。如果采用這些技術(shù),必須使用某種緩存技術(shù)來(lái)獲得適當(dāng)?shù)男阅?。不可能?dòng)態(tài)生成每個(gè)頁(yè)面。

 

回頁(yè)首

結(jié)束語(yǔ)

如果不需要處理混合內(nèi)容,SimpleXML 對(duì)于 PHP 程序員的工具箱來(lái)說(shuō)是個(gè)不錯(cuò)新玩意。其適用的情況很多。具體而言,它能夠很好地處理簡(jiǎn)單的、類似記錄的數(shù)據(jù)。只要文檔層次不深、不很復(fù)雜,而且沒(méi)有混合內(nèi)容,SimpleXML 要比使用 DOM 簡(jiǎn)單得多。如果事先知道文檔結(jié)構(gòu)該工具將更有用,雖然通過(guò) XPath 可以滿足這種要求。雖然不支持驗(yàn)證和混合內(nèi)容有點(diǎn)不方便,但不是絕對(duì)的。很多簡(jiǎn)單格式?jīng)]有混合內(nèi)容,而且很多應(yīng)用只涉及到可預(yù)知的數(shù)據(jù)格式。如果符合您的需要,可以自己嘗試一下 SimpleXML。只要對(duì)錯(cuò)誤處理稍加注意,并且通過(guò)緩存來(lái)解決性能問(wèn)題,SimpleXML 可以成為 PHP 中一種可靠、健壯的 XML 處理方法。


分享標(biāo)題:PHP中的SimpleXML處理-創(chuàng)新互聯(lián)
URL鏈接:http://weahome.cn/article/jdjss.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部