明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

PHP5的XML新特征

[摘要]面向的讀者 這篇文章的面向?qū)ο笫撬袑?duì)PHP5的XML新功能感興趣的各個(gè)水平的PHP開發(fā)者。我們假定讀者掌握XML的基本知識(shí)。然而,如果你已經(jīng)在你的PHP當(dāng)中使用了XML,那么這篇文章也會(huì)讓你受益非淺。 介紹 在當(dāng)今的互聯(lián)網(wǎng)世界,XML已經(jīng)不再是一個(gè)時(shí)髦詞了,它已經(jīng)被廣泛的接受和規(guī)范的使用了。因此...

面向的讀者

這篇文章的面向?qū)ο笫撬袑?duì)PHP5的XML新功能感興趣的各個(gè)水平的PHP開發(fā)者。我們假定讀者掌握XML的基本知識(shí)。然而,如果你已經(jīng)在你的PHP當(dāng)中使用了XML,那么這篇文章也會(huì)讓你受益非淺。

介紹

在當(dāng)今的互聯(lián)網(wǎng)世界,XML已經(jīng)不再是一個(gè)時(shí)髦詞了,它已經(jīng)被廣泛的接受和規(guī)范的使用了。因此相對(duì)于PHP4,PHP5對(duì)于XML的支持更受到了重視。在PHP4中你面對(duì)的幾乎都是非標(biāo)準(zhǔn),API中斷,內(nèi)存泄漏以及其它不完全的功能。盡管有些不足已經(jīng)在PHP4.3中得到改進(jìn),開發(fā)者們還是決定拋棄原有的代碼,在PHP5重寫全部代碼。

這篇文章將對(duì)PHP5中關(guān)于XML的所有令人激動(dòng)的新特性逐一介紹。

PHP4 的 XML

早期的PHP版本就已經(jīng)開始支持XML了,而這只是一個(gè)基于SAX的接口,它可以輕松的解析任何XML文檔。隨著PHP4中加入了DOMXML擴(kuò)展模塊,XML被更好的支持了。后來XSLT做為補(bǔ)充被加了進(jìn)來。在整個(gè)PHP4的階段,其它一些功能如HTML,XSLT和DTD驗(yàn)證也被加到了DOMXML擴(kuò)展中,不幸的是,由于XSLT和DOMXML擴(kuò)展始終處于實(shí)驗(yàn)階段,API部分也被不止一次的修改,它們還是不能以默認(rèn)方式安裝。此外,DOMXML擴(kuò)展沒有遵循W3C制定的DOM標(biāo)準(zhǔn),而有自己的命名方法。雖然在PHP4.3中這部分得到了改善并且許多內(nèi)存泄漏和其它一些功能也得以修復(fù),但它始終沒有發(fā)展到一個(gè)穩(wěn)定的階段,一些深入的問題已經(jīng)幾乎不可能修復(fù)。只有SAX擴(kuò)展被已默認(rèn)方式安裝,其它的一些擴(kuò)展從未得到廣泛的使用。

基于所有這些原因,PHP的XML開發(fā)者決定在PHP5重寫全部代碼,并遵循使用標(biāo)準(zhǔn)。

PHP5的XML
在PHP5中所有支持XML的部分幾乎全部重新編寫.現(xiàn)在的所有XML擴(kuò)展都是基于GNOME項(xiàng)目的LIBXML2庫。這將允許在不同的擴(kuò)展模塊之間互相操作,核心開發(fā)者只需要在一個(gè)底層的庫上進(jìn)行開發(fā)。例如,復(fù)雜的內(nèi)存管理只實(shí)現(xiàn)一次就可以讓所有XML相關(guān)擴(kuò)展得到改善。

除了繼承PHP4中聞名的SAX解析器之外,PHP5還支持遵循W3C標(biāo)準(zhǔn)的DOM和基于LIBXSLT引擎的XSLT。同時(shí)還加入了PHP獨(dú)有的SimpleXML擴(kuò)展和符合標(biāo)準(zhǔn)的SOAP擴(kuò)展。隨著XML越來越被重視,PHP開發(fā)者決定在默認(rèn)安裝方式中加入更多對(duì)XML的支持。這就意味著你現(xiàn)在可以使用SAX,DOM和SimpleXML,而這些擴(kuò)展將會(huì)在更多的服務(wù)器上安裝。然后對(duì)于XSLT和SOAP的支持,還需要在PHP編譯時(shí)被顯式的配置。

數(shù)據(jù)流的支持

現(xiàn)在所有的XML擴(kuò)展都支持PHP數(shù)據(jù)流,即使你不從PHP中直接訪問。例如,在PHP5中你可以從一個(gè)文件或從一條指令訪問數(shù)據(jù)流;旧夏隳軌蛟谌魏慰梢栽L問普通文件的地方訪問PHP數(shù)據(jù)流。

PHP4.3中簡(jiǎn)要的介紹了數(shù)據(jù)流,在PHP5中已經(jīng)得到了進(jìn)一步的提高,包含文件存取,網(wǎng)絡(luò)存取和其它操作,如共享一套功能函數(shù)。你甚至可以使用PHP代碼來實(shí)現(xiàn)你自己的數(shù)據(jù)流,這樣數(shù)據(jù)存取將變得非常簡(jiǎn)單。關(guān)于這部分的更多細(xì)節(jié)請(qǐng)參考PHP文檔。

SAX

SAX的全稱是Simple API for XML,它是用于解析XML文檔的接口,是基于回調(diào)形式的。從PHP3開始就已經(jīng)支持了SAX,到現(xiàn)在也沒有太大的變化。在PHP5中,API接口并沒有改變,所以你的代碼仍然可以運(yùn)行。唯一不同的是它不再基于EXPAT庫,而是基于LIBXML2庫。

這個(gè)變化帶來了一些對(duì)命名空間支持上的問題,這個(gè)問題在LIBXML2.2.6版本中已經(jīng)得到解決。但是LIBXML2以前的版本中并沒有解決,因此如果你使用了xml_parse_create_ns();強(qiáng)烈建議在你的系統(tǒng)上安裝LIBXML2.2.6。

DOM

DOM (文檔對(duì)象模型)是由W3C制定的一套訪問XML文檔樹的標(biāo)準(zhǔn)。在PHP4可以使用DOMXML來對(duì)此進(jìn)行操作,DOMXML的最主要問題是它不符合標(biāo)準(zhǔn)的命名方法。而且在很長(zhǎng)一段時(shí)間內(nèi)還存在內(nèi)存泄漏問題(PHP4.3已經(jīng)修復(fù)了這個(gè)問題)。

新的DOM擴(kuò)展是基于W3C標(biāo)準(zhǔn)完成的,包含方法和屬性名稱。如果你在其它語言中熟悉DOM,例如在JavaScript中,那么在PHP中編寫類似的功能將變得非常容易。你不必每次都查看文檔,因?yàn)榉椒ê蛥?shù)都是相同的。

由于使用了新的W3C標(biāo)準(zhǔn),基于DOMXML的代碼將不能運(yùn)行。在PHP中的API有很大的不同。但是如果你的代碼中使用了類似W3C標(biāo)準(zhǔn)的方法命名方式,移植并不是很困難。你只需要將載入函數(shù)和保存函數(shù)修改,刪除函數(shù)名中的下劃線(DOM標(biāo)準(zhǔn)使用首字母大寫)。其它各處的調(diào)節(jié)當(dāng)然也是必須的,但是主要邏輯部分可以保持不變。

讀取DOM

我不會(huì)在這篇文章中解釋DOM擴(kuò)展的所有特性,那也是沒有必要的;蛟S你應(yīng)該將HTTP://www.w3.org/DOM的文檔加入書簽。它與PHP5的DOM部分基本上相同。

在這篇文章的大多數(shù)例子中我們將使用同一個(gè)XML文件,zend.com上有非常簡(jiǎn)單的RSS版本。將下面的文本粘貼到一個(gè)文本文件中并保存為articles.xml。





http://www.zend.com/zend/week/week172.php



http://www.zend.com/zend/tut/tut-hatwar3.php



要將這個(gè)例子載入到一個(gè)DOM對(duì)象,首先要?jiǎng)?chuàng)建一個(gè)DOMDocument對(duì)象,然后載入XML文件。

$dom = new DomDocument();
$dom->load("articles.xml");

正像上面所提及的,你可以使用PHP的數(shù)據(jù)流來載入一個(gè)XML文檔,你應(yīng)該這樣寫:

$dom->load("file:///articles.xml");

(或者其它類型的數(shù)據(jù)流)

如果你想將XML文檔輸出到瀏覽器或做為標(biāo)準(zhǔn)標(biāo)出,使用:

print $dom->saveXML();

如果你想把它保存成文件,請(qǐng)使用:

print $dom->save("newfile.xml");

(注意這樣做會(huì)將文件大小發(fā)送到stdout)

當(dāng)然這個(gè)例子沒有太多的功能,讓我們來做些更有用的。我們來取得所有的title元素。有很多方法可以辦到,最簡(jiǎn)單的就是使用getElementsByTagName($tagname):

$titles = $dom->getElementsByTagName("title");
foreach($titles as $node) {
print $node->textContent . "\n";
}

textContent屬性并不是W3C標(biāo)準(zhǔn),它可以讓我們很方便的快速讀取一個(gè)元素的所有文本節(jié)點(diǎn),使用W3C的標(biāo)準(zhǔn)讀取是下面這樣:

$node->firstChild->data;

(這時(shí)候你要確保firstChild結(jié)點(diǎn)是你需要的文本結(jié)點(diǎn),否則你還得遍歷所有子結(jié)點(diǎn)來查找)。

另外一個(gè)要注意的問題是getElementsByTagName()返回一個(gè)DomNodeList,對(duì)象,而不是像PHP4中g(shù)et_elements_by_tagname()那樣返回一個(gè)數(shù)組,但是正像你在這個(gè)例子中看到的那樣,你可以使用foreach語句輕松的遍歷它。你也可以直接使用$titles->item(0)來訪問結(jié)點(diǎn)。該方法將返回第一個(gè)title元素。

另一個(gè)取得所有title元素的辦法是從根結(jié)點(diǎn)遍歷,你可以看到,這個(gè)方法更復(fù)雜,但是如果你需要的不只是title元素的時(shí)候,這個(gè)方法也就更靈活。

foreach ($dom->documentElement->childNodes as $articles) {
//如果節(jié)點(diǎn)是一個(gè)元素(nodeType == 1)并且名字是item就繼續(xù)循環(huán)
if ($articles->nodeType == 1 && $articles->nodeName == "item") {
foreach ($articles->childNodes as $item) {
//如果節(jié)點(diǎn)是一個(gè)元素,并且名字是title就打印它.
if ($item->nodeType == 1 && $item->nodeName == "title") {
print $item->textContent . "\n";
}
}
}
}

XPath
XPaht 就像是XML的SQL,使用XPath你可以在一個(gè)XML文檔中查詢符合一些模式語法的特定結(jié)點(diǎn)。想使用XPath獲得所有title結(jié)點(diǎn),只需要這么做:


$xp = new domxpath($dom);
$titles = $xp->query("/articles/item/title");
foreach ($titles as $node) {
print $node->textContent . "\n";
}
?>

這樣和使用getElementsByTagName()方法差不多,但是Xpath要強(qiáng)大的多,例如,如果我們有一個(gè)title元素是article的子元素(而不是item的子元素),getElementsByTagName()就會(huì)將它返回。而使用/articles/item/title語法,我們只會(huì)得到在指定深度和位置的title元素。這只是一個(gè)簡(jiǎn)單的例子,再深入一點(diǎn)可能是這樣:

/articles/item[position() = 1]/title 返回第一個(gè)item元素的所有

/articles/item/title[@id = '23'] 返回所有含有id屬性并且值為23的title

/articles//title 返回所有articles元素下面的title(譯者注://代表任意深度)

你也可以查詢含有特殊兄弟元素的點(diǎn),含有特殊文本內(nèi)容的元素,或者使用命名空間等等。如果你必須大量的查詢XML文檔,適當(dāng)?shù)膶W(xué)習(xí)使用XPath會(huì)節(jié)省你很多時(shí)間,它使用簡(jiǎn)單,執(zhí)行速度快,比標(biāo)準(zhǔn)的DOM需要更少的代碼。

向DOM中寫入數(shù)據(jù)
文檔對(duì)象模型并不是只能讀取和查詢,你也可以操作和寫入。(DOM標(biāo)準(zhǔn)有點(diǎn)冗長(zhǎng),因?yàn)榫帉懻呦氡M量支持能夠想像到的每一個(gè)環(huán)境,但是它工作的非常好)?纯聪旅孢@個(gè)例子,它在我們的article.xml文件中添加了一個(gè)新元素。

$item = $dom->createElement("item");
$title = $dom->createElement("title");
$titletext = $dom->createTextNode("XML in PHP5");
$title->appendChild($titletext);
$item->appendChild($title);
$dom->documentElement->appendChild($item);
print $dom->saveXML();

首先,我們創(chuàng)建了所有需要的結(jié)點(diǎn),一個(gè)item元素,一個(gè)title元素和一個(gè)包含item標(biāo)題的文本結(jié)點(diǎn),然后我們將所有的結(jié)點(diǎn)鏈接起來,把文本結(jié)點(diǎn)加到title元素上,把title元素加到item元素上,最后我們把item元素插入到articles根元素上。現(xiàn)在,我們的XML文檔中有一個(gè)新的文章列表了。

擴(kuò)展類(class)
好了,上面的例子都可以在PHP4下面用DOMXML擴(kuò)展來做(只是API有一些不同),能夠自己擴(kuò)展DOM類是PHP5的一個(gè)新特性,這使得書寫更多可讀性強(qiáng)的代碼變得可能。下面是用DOMDocument類重新寫的整個(gè)例子:

class Articles extends DomDocument {
function __construct() {
//必須調(diào)用!
parent::__construct();
}

function addArticle($title) {
$item = $this->createElement("item");
$titlespace = $this->createElement("title");
$titletext = $this->createTextNode($title);
$titlespace->appendChild($titletext);
$item->appendChild($titlespace);
$this->documentElement->appendChild($item);
}
}
$dom = new Articles();
$dom->load("articles.xml");
$dom->addArticle("XML in PHP5");
print $dom->save("newfile.xml");

HTML
PHP5中一個(gè)經(jīng)常不被注意到的特性是libxml2庫對(duì)HTML的支持,你不僅可以使用DOM擴(kuò)展載入結(jié)構(gòu)良好(well-formed)的XML文檔,還可以載入非結(jié)構(gòu)良好的(not-well-formed)HTML文檔,把它當(dāng)做標(biāo)準(zhǔn)的DOMDocument對(duì)象,使用所有能用的方法和特性,比如XPath和SimpleXML。

當(dāng)你需要訪問一個(gè)你無法控制站點(diǎn)的內(nèi)容時(shí),HTML的性能就顯示十分有用了。在 XPath, XSLT 或 SimpleXML的幫助下,你省掉了許多代碼,像使用正則表達(dá)式比較字符串或者SAX解析器。當(dāng)HTML文檔結(jié)構(gòu)不是很好的時(shí)候,這個(gè)辦法尤其有用(這是個(gè)頻繁的問題!)。

下面的代碼獲得并解析php.net的首頁,將返第一個(gè)title元素的內(nèi)容。

$dom = new DomDocument();
$dom->loadHTMLFile("http://www.php.net/");
$title = $dom->getElementsByTagName("title");
print $title->item(0)->textContent;

請(qǐng)注意當(dāng)指定元素沒有找到時(shí),你的輸出可能會(huì)包含錯(cuò)誤。如果你的網(wǎng)站還在使用PHP輸出HTML4代碼,有一個(gè)好消息要告訴你,DOM擴(kuò)展不僅能載入HTML文檔,而且還能將他們保存為HTML4格式的文件。在你添加完DOM文檔后,使用$dom->saveHTML()來保存。要注意的是,為了使輸出的HTML代碼符合W3C標(biāo)準(zhǔn),最好不用使用 整齊的擴(kuò)展?(tidy extension)。Libxml2 庫支持的HTML并不會(huì)考慮到每個(gè)可能發(fā)生的事情,也不能很好的處理非通用格式的輸入。

驗(yàn)證
XML文檔的驗(yàn)證越來越重要了。例如,如果你從一些國(guó)外資源中獲得了一個(gè)XML文檔,在你處理之前你需要檢驗(yàn)它是否符合某個(gè)確定的格式。幸運(yùn)的是你不需要在PHP中寫自己的驗(yàn)證程序,因?yàn)槟憧梢允褂萌齻(gè)應(yīng)用最廣泛的標(biāo)準(zhǔn)之一(DTD,XML Schema 或RelaxNG)來完成它。.

DTD是一個(gè)產(chǎn)生于SGML時(shí)代的標(biāo)準(zhǔn),缺少一些XML的新特性(如命名空間),而且由于它不是用XML寫的,它也很難被解析和轉(zhuǎn)換。
XML Schemai是由W3C制定的一個(gè)標(biāo)準(zhǔn),它應(yīng)用廣泛,幾乎包含了所有驗(yàn)證XML文檔所需要的內(nèi)容。
RelaxNG 是復(fù)雜的XML Schema標(biāo)準(zhǔn)的對(duì)頭,是由自由者組織創(chuàng)建的,由于它比XML Schema更容易實(shí)現(xiàn),越來越多的程序開始支持RelaxNG了
如果你沒有遺留下來的計(jì)劃文檔或者非常復(fù)雜的XML文檔,那么使用RelaxNG吧。它書寫和閱讀都比較簡(jiǎn)單,越來越多的工具也支持它。甚至還有一個(gè)工具叫Trang,它可以從XML范本中自動(dòng)創(chuàng)建一個(gè)RelaxNG文檔。而且只有RelaxNG(和老化的DTDS)被libxml2完全支持,盡管libxml2也即將完全支持ML Schema。

驗(yàn)證XML文檔的語法相當(dāng)簡(jiǎn)單:

$dom->validate('articles.dtd');
$dom->relaxNGValidate('articles.rng');
$dom->schemaValidate('articles.xsd');
目前,所有這些都只會(huì)簡(jiǎn)單的返回true或false,錯(cuò)誤會(huì)被做為PHP警告輸出。顯然想返回給用戶友好的信息這并不是一個(gè)好主意,在PHP5.0以后的版本里會(huì)有所改善。到底該怎么實(shí)現(xiàn)目前還在討論之中,但是錯(cuò)誤報(bào)告肯定會(huì)處理的更好。

SimpleXML
SimpleXML 是PHP的XML家族中最后一個(gè)被加入的成員,加入SimpleXML擴(kuò)展的目的是為了提供一個(gè)使用標(biāo)準(zhǔn)對(duì)象屬性和迭代器訪問XML文檔的更簡(jiǎn)單的方法。該擴(kuò)展沒有太多的方法,雖然如此它還是相當(dāng)強(qiáng)大的。從我們的文檔的取得所有title節(jié)點(diǎn)比原來需要更少的代碼。

$sxe = simplexml_load_file("articles.xml");
foreach($sxe->item as $item) {
print $item->title ."\n";
}

這是在干什么?首先將articles.xml載入到一個(gè)SimpleXML對(duì)象。然后取得所有$sxe中的item元素,最后$item->title返回title元素的內(nèi)容,就是這樣。你也可以使用關(guān)聯(lián)數(shù)組查詢屬性,使用: $item->title['id']。

看到了吧,這后面真是太神奇了,有許多不同的辦法可以得到我們想要的結(jié)果,例如, $item->title[0]返回和例子中相同的結(jié)果,另一方面,foreach($sxe->item->title as $item)只返回第一個(gè)title,并不是所有在文檔中的title元素。(就像我在XPath中預(yù)期的那樣)。

SimpleXML 實(shí)際上是使用了Zend引擎2新特性的第一個(gè)擴(kuò)展。因此也成了這些新特性的測(cè)試點(diǎn),你要知道在開發(fā)階段bugs和不可預(yù)料的錯(cuò)誤可不是少數(shù)。

除了上面例子中所使用的遍歷所有節(jié)點(diǎn)的方法,在SimpleXML中也有一個(gè)XPath接口,它為訪問單個(gè)結(jié)點(diǎn)提供了更簡(jiǎn)單的辦法。

foreach($sxe->xpath('/articles/item/title') as $item) {
print $item . "\n";
}

不可否認(rèn),這段代碼也不比前面例子中的短,但是提供了更復(fù)雜或更深的嵌套XML文檔,你會(huì)發(fā)現(xiàn)和SimpleXML一起使用XPath會(huì)節(jié)省你很多的輸入。

向 SimpleXML 文檔寫入數(shù)據(jù)
你不僅可以解析和讀取SimpleXML,而且還可以改變SimpleXML文檔。至少我們加入一些擴(kuò)展:

$sxe->item->title = "XML in PHP5 "; //title元素的新內(nèi)容。
$sxe->item->title['id'] = 34; // title元素的新屬性。
$xmlString = $sxe->asXML(); // 將SimpleXML對(duì)象做為序列化的XML字符串返回
print $xmlString;

互用協(xié)作性
由于SimpleXML也是基于libxml2庫的,你可以在幾乎不影響速度的情況下輕松的將SimpleXML對(duì)象轉(zhuǎn)化成DomDocument對(duì)象。(文檔不用進(jìn)行內(nèi)部復(fù)制),由于這個(gè)機(jī)制,你擁有了二個(gè)對(duì)象的最好部分,使用一個(gè)適合你手頭工作的工具吧,它是這樣使用的:

$sxe = simplexml_import_dom($dom);
$dom = dom_import_simplexml($sxe);
XSLT
XSLT是用來將XML文檔轉(zhuǎn)換為其它XML文檔的語言,XSLT本身是用XML編寫的,屬于功能性語言家族,在程序處理上和面對(duì)對(duì)象語言(像PHP)有所不同。PHP4中有二種XSLT處理器:Sablotron(在廣泛使用的XSLT擴(kuò)展中)和Libxslt(在domxml擴(kuò)展中),這兩種API不互相兼容,并且使用方法也不相同。PHP5只支持libxslt處理器,之所以選擇它是因?yàn)樗腔贚ibxml2的,因此也更符合PHP5的XML概念。

理論上將Sablotron綁定到PHP5上也是可能的,但是不幸的是沒人來做。因此,如果你正在使用Sablotron,你不得不在PHP5中切換到libxslt處理器。Libxslt 是帶有JavaScript異常處理支持的Sablotron,甚至可以使用PHP強(qiáng)大的數(shù)據(jù)流來重新實(shí)現(xiàn)Sablotron獨(dú)有的計(jì)劃處理(scheme handlers)。此外,libxslt 是 最快的XSLT處理器之一,所以你還免費(fèi)得到了速度的提升。(執(zhí)行速度是Sablotron的二倍)。

和本文討論的其它擴(kuò)展一樣,你可以在XSL擴(kuò)展,DOM擴(kuò)展和vice versa之間交換XML文檔,實(shí)際上,你必須得這么做,因?yàn)镋XT/XSL擴(kuò)展并沒有載入和保存XML文檔的接口,只能使用DOM擴(kuò)展。一開始學(xué)習(xí)XSLT轉(zhuǎn)換,你不需要掌握太多的內(nèi)容,這里也不存在W3C標(biāo)準(zhǔn),因?yàn)檫@個(gè)API中從Mozilla“借”過來的。

首先你需要一個(gè)XSLT樣式表,將下列文本粘貼到一個(gè)新文件并且保存灰articls.xsl















然后用PHP腳本調(diào)用它::



/* 將XML和XSL文檔載入到DOMDocument對(duì)象*/
$xsl = new DomDocument();
$xsl->load("articles.xsl");
$inputdom = new DomDocument();
$inputdom->load("articles.xml");

/* 創(chuàng)建XSLT處理器,并導(dǎo)入樣式表*/
$proc = new XsltProcessor();
$xsl = $proc->importStylesheet($xsl);
$proc->setParameter(null, "titles", "Titles");

/* 轉(zhuǎn)換并輸出XML文檔 */
$newdom = $proc->transformToDoc($inputdom);
print $newdom->saveXML();

?>

上面的例子首先使用DOM的方法load()載入XSLT樣式表articles.xsl,然后創(chuàng)建了一個(gè)新的XsltProcessor對(duì)象,該對(duì)象導(dǎo)到了后面要使用了XSLT樣式表對(duì)象,參數(shù)可以這樣設(shè)置setParameter(namespaceURI, name, value),最后XsltProcessor對(duì)象使用transformToDoc($inputdom)開始轉(zhuǎn)換并返回一個(gè)新的DOMDocument對(duì)象。

. 這個(gè)API的優(yōu)點(diǎn)在于你可以使用同一個(gè)樣式表轉(zhuǎn)換許多XML文檔,只需要將它載入一次然后重復(fù)使用它,因?yàn)閠ransormToDoc()函數(shù)可以應(yīng)用于不同的XML文檔。

除了transormToDoc(),還有二個(gè)用于轉(zhuǎn)換的方法:transformToXML($dom)返回一個(gè)字符串,transformToURI($dom, $uri)將轉(zhuǎn)換之后的文檔保存到文件或一個(gè)PHP數(shù)據(jù)流。注意如果你想使用XSLT的一個(gè)語法如 或 indent="yes",你不能使用transformToDoc(),因?yàn)镈OMDocument對(duì)象 不能保存該信息,只能當(dāng)你將轉(zhuǎn)換后的結(jié)果直接保存到字符串或文件中時(shí)才能這樣做。

調(diào)用PHP函數(shù)
XSLT擴(kuò)展最后一個(gè)新加的特性是能夠在XSLT 樣式表內(nèi)部調(diào)用任何PHP函數(shù),主張正統(tǒng)的XML支持者一定不會(huì)喜歡這個(gè)功能(這樣的樣式表有點(diǎn)復(fù)雜,很容易混淆邏輯和設(shè)計(jì)),在某些地方卻是十分有用的。當(dāng)涉及到函數(shù)時(shí)XSLT就變得很有限,即使想實(shí)現(xiàn)用不同的語言輸出一個(gè)日期也是非常麻煩的。但是使用這個(gè)功能,處理這些就和只使用PHP一樣容易。下面是向XSLT添加一個(gè)函數(shù)的代碼:



function dateLang () {
return strftime("%A");
}

$xsl = new DomDocument();
$xsl->load("datetime.xsl");
$inputdom = new DomDocument();
$inputdom->load("today.xml");

$proc = new XsltProcessor();
$proc->registerPhpFunctions();

// 載入文檔并使用$xsl來處理
$xsl = $proc->importStylesheet($xsl);

/* 轉(zhuǎn)換并輸出XML文檔 */
$newdom = $proc->transformToDoc($inputdom);

print $newdom->saveXML();

?>

下面是XSLT樣式表datetime.xsl,它會(huì)調(diào)用這個(gè)函數(shù)。








下面是要使用樣式表轉(zhuǎn)換的XML文檔,today.xml(同理,articles.xml也會(huì)得到同樣結(jié)果)。




上面的樣式表,PHP腳本和所有的XML文件會(huì)用當(dāng)前系統(tǒng)設(shè)置的語言輸出星期的名字。你可以給php:function()添加更多的參數(shù),添加的參數(shù)會(huì)被傳遞給PHP函數(shù)。這里有一個(gè)函數(shù)php:functionString(),這個(gè)函數(shù)自動(dòng)將所有輸入的參數(shù)轉(zhuǎn)換為字符串,所以你不需要在PHP里進(jìn)行轉(zhuǎn)換。

注意你需要在轉(zhuǎn)換之前調(diào)用$xslt->registerPhpFunctions(),否則PHP函數(shù)調(diào)用將因?yàn)榘踩虿粫?huì)被執(zhí)行(你始終相信你的XSLT樣式表嗎?)。目前訪問系統(tǒng)還沒有實(shí)現(xiàn),也許在將來PHP5的版本中會(huì)實(shí)現(xiàn)這個(gè)功能。

摘要
PHP對(duì)XML的支持已經(jīng)向前邁進(jìn)了一大步,它符合標(biāo)準(zhǔn),功能強(qiáng)大,互用協(xié)作性強(qiáng),被作為默認(rèn)選項(xiàng)安裝,已被授權(quán)使用。新加入的SimpleXML擴(kuò)展提供了簡(jiǎn)單快速訪問XML文檔的方法,可以節(jié)省你很多的代碼,尤其是當(dāng)你有結(jié)構(gòu)化文檔或者可以使用強(qiáng)大的XPath時(shí)。

感謝libxml2—PHP5 XML擴(kuò)展所使用的底層庫,使用DTD,RelaxNG或XML Schema驗(yàn)證XML文檔現(xiàn)在已經(jīng)被支持了。

XSL支持也得到了翻新,現(xiàn)在使用Libxslt庫,比原來的Sablotron庫在性能上有很大提高,而且,在XSLT樣式表內(nèi)部調(diào)用PHP函數(shù)可以讓你寫出更強(qiáng)大的XSLT代碼。

如果你已經(jīng)在PHP4或其它語言中使用了XML,你會(huì)喜歡PHP5的XML特性的,XML在PHP5中有了很大的變化,符合標(biāo)準(zhǔn),和其它工具,語言是同等的。(出處:Viphot)


標(biāo)簽:PHP5的XML新特征