|
XML(可擴(kuò)展的標(biāo)注語(yǔ)言)是一種W3C標(biāo)準(zhǔn),主要用于Web應(yīng)用程序和服務(wù)器之間實(shí)現(xiàn)容易的交互、數(shù)據(jù)的存儲(chǔ)與使用。
使用XML標(biāo)準(zhǔn)編碼的數(shù)據(jù)具有能容易被人和計(jì)算機(jī)解釋的意義和結(jié)構(gòu)。XML數(shù)據(jù)是平臺(tái)和應(yīng)用程序獨(dú)立的。不用多說(shuō),這本身就使XML成為適合于互聯(lián)網(wǎng)的一個(gè)理想的數(shù)據(jù)交換格式(事實(shí)上,它正是因這一用途而被開(kāi)發(fā)的)。最近,寬帶連接的增長(zhǎng)及消費(fèi)者對(duì)于越過(guò)任何媒體進(jìn)行數(shù)據(jù)共享的應(yīng)用軟件的需求意味著,XML Web服務(wù)和應(yīng)用軟件正變得越來(lái)越豐富。
XML的發(fā)明正是為了解決描述網(wǎng)上豐富的數(shù)據(jù)的組織問(wèn)題;而目前為止,這一問(wèn)題僅能夠通過(guò)HTML的巧妙使用得到部分地解決。
下面是一XML文檔的實(shí)例:
程序代碼
復(fù)制代碼 代碼如下:
<?xml version="1.0"?>
<party>
<location>My House</location>
<time>7pm</time>
<guest>
<name>John Bloggs</name>
<item>Crate of Fosters</item>
</guest>
<guest>
<name>Sara Bloggs</name>
<item>Umbrella</item>
</guest>
<guest>
<name>David Fig</name>
<item>Bombay Mix</item>
</guest>
</party>
如果你以前沒(méi)見(jiàn)過(guò)XML,那么你可以認(rèn)為它看起來(lái)象HTML。HTML是一種SGML應(yīng)用程序,而XML是它的一個(gè)子集。然而,其相似性還包括它們具有相似的標(biāo)注分隔符。
僅需看一下上面的XML片斷,我們就能看到,該數(shù)據(jù)是描述一個(gè)具有一些客人的聚會(huì);其中,每一個(gè)客人相應(yīng)于一項(xiàng)。用于描述數(shù)據(jù)的標(biāo)簽名完全由作者來(lái)選擇。所有XML標(biāo)準(zhǔn)要求:數(shù)據(jù)必須是一致的并且用于描述數(shù)據(jù)的標(biāo)簽為良構(gòu)的。我們可以進(jìn)一步用一種文檔類型聲明(DTD)或一個(gè)XML模式來(lái)強(qiáng)制數(shù)據(jù)的完整性。然而為簡(jiǎn)化起見(jiàn),我們?cè)诒疚闹袑H使用普通的XML。
二、 XML應(yīng)用程序
剛才,我們已經(jīng)看到了如何使用XML來(lái)描述任何種類的數(shù)據(jù)。事實(shí)上,XML已經(jīng)在今天的許多Web應(yīng)用程序中得到廣泛使用,下面是一些著名的應(yīng)用描述:
? XHTML-這是使用最廣泛的XML應(yīng)用程序之一。它類似基于HTML的SGML-用于描述數(shù)據(jù)在網(wǎng)頁(yè)上的顯示方式。XHTML使用一DTD來(lái)確保所有的文檔遵循標(biāo)準(zhǔn)。XHTML的出現(xiàn)使Web程序員的開(kāi)發(fā)稍微容易了一些;然而,一種完全兼容于CSS和XHTML標(biāo)準(zhǔn)的web瀏覽器尚未出現(xiàn)。
? XML-RPC-遠(yuǎn)程過(guò)程調(diào)用(RPC),應(yīng)用于分布式應(yīng)用程序中以調(diào)用遠(yuǎn)程計(jì)算機(jī)上的過(guò)程。XML-RPC使用XML對(duì)關(guān)于過(guò)程調(diào)用的信息進(jìn)行編碼,并且使用HTTP把它發(fā)送到接收計(jì)算機(jī)。然后,過(guò)程的返回值被再次用XML編碼并用HTTP連接發(fā)送回調(diào)用者計(jì)算機(jī)。
? RSS-真正簡(jiǎn)單的聚合/豐富的站點(diǎn)摘要,它是一種用來(lái)聚合web站點(diǎn)內(nèi)容(例如新聞、文章、共享價(jià)格和鏈接等)的方法,它用一個(gè)特殊的應(yīng)用程序(一個(gè)聚合器)定期更新用戶PC上的RSS回饋。該RSS數(shù)據(jù)是使用XML進(jìn)行編碼和傳輸?shù)摹?
? AJAX-異步的JavaScript和XML,允許web開(kāi)發(fā)者創(chuàng)建具有豐富特征的事件驅(qū)動(dòng)的運(yùn)行在web瀏覽器上的web應(yīng)用程序。其中,JavaScript用于把XML編碼的數(shù)據(jù)發(fā)送到服務(wù)器端腳本(或從服務(wù)器端接收XML編碼的數(shù)據(jù)),并允許局部的實(shí)時(shí)的頁(yè)面更新而不需要更新所有頁(yè)面內(nèi)容。
上面僅僅是XML的可能的應(yīng)用的一部分。在以后文章中,我們將分析如何在php中使用這些應(yīng)用軟件。
三、 在php中使用XML
自從php 5.0以來(lái),php能與XML交互的可用選項(xiàng)顯著地增加。而php版本4所能提供的是不穩(wěn)定的而且是非w3c兼容的DOM XML擴(kuò)展。
下面,我將集中討論php 5所提供給我們的三個(gè)允許我們與XML交互的方法:DOM,簡(jiǎn)單XML和XPath。在可能之處,我將建議最適合于每種方法的條件和數(shù)據(jù)。所有的示例代碼將使用XML數(shù)據(jù)源來(lái)描述一個(gè)庫(kù)及其中包含的書。
程序代碼
復(fù)制代碼 代碼如下:
<xml version="1.0"?>
<library>
<categories>
<category cid="1">Web Development</category>
<category cid="2">Database Programming</category>
<category cid="3">php</category>
<category cid="4">Java</category>
</categories>
<books>
<book>
<title>Apache 2</title>
<author>Peter Wainwright</author>
<publisher>Wrox</publisher>
<category>1</category>
</book>
<book>
<title>Advanced php Programming</title>
<author>George Schlossnagle</author>
<publisher>Developer Library</publisher>
<category>1</category>
<category>3</category>
</book>
<book>
<title>Visual FoxPro 6 - Programmers Guide</title>
<author>Eric Stroo</author>
<publisher>Microsoft Press</publisher>
<category>2</category>
</book>
<book>
<title>Mastering Java 2</title>
<author>John Zukowski</author>
<publisher>Sybex</publisher>
<category>4</category>
</book>
</books>
</library>
四、 DOM
DOM php擴(kuò)展名允許使用W3C DOM API在XML文檔上進(jìn)行操作。在php 5出現(xiàn)之前,這是php能存取XML文檔的唯一方法。如果你在JavaScript中使用了DOM,那么會(huì)認(rèn)識(shí)到這些對(duì)象模型幾乎是一樣的。
由于DOM方法在遍歷和操作XML文檔時(shí)比較羅嗦,所以任何DOM兼容的代碼都有明顯的優(yōu)點(diǎn)-與任何其它實(shí)現(xiàn)相同的W3C兼容的對(duì)象模型的API兼容。
在下面的實(shí)例代碼中,我們使用DOM來(lái)顯示關(guān)于每本書的信息。首先,我們遍歷一下列表目錄,把它們的Id和相應(yīng)的名字裝載到一個(gè)索引數(shù)組中。然后,我們顯示每本書的一個(gè)簡(jiǎn)短描述:
php:
復(fù)制代碼 代碼如下:
<?php
/*這里我們必須指定XML版本:也即是1.0 */
$xml = new DomDocument('1.0');
$xml->load('xml/library.xml');
/*首先,創(chuàng)建一個(gè)目錄列表*/
$categories = array();
$XMLCategories = $xml->getElementsByTagName('categories')->item(0);
foreach($XMLCategories->getElementsByTagName('category') as $categoryNode) {
/*注意我們是如何得到屬性的*/
$cid = $categoryNode->getAttribute('cid');
$categories[$cid] = $categoryNode->firstChild->nodeValue;
}
?>
<html>
<head>
<title>XML Library</title>
</head>
<body>
<?
php foreach($xml->getElementsBytagName('book') as $book):
/*查找標(biāo)題*/
$title = $book->getElementsByTagName('title')->item(0)->firstChild->nodeValue;
/*查找作者-為了簡(jiǎn)化起見(jiàn),我們假設(shè)僅僅有一個(gè)作者*/
$author = $book->getElementsByTagName('author')->item(0)->firstChild->nodeValue;
/* 列表目錄*/
$bookCategories = $book->getElementsByTagName('category');
$catList = '';
foreach($bookCategories as $category) {
$catList .= $categories[$category->firstChild->nodeValue] . ', ';
}
$catList = substr($catList, 0, -2); ?>
<div>
<h2><?php echo($title) ?></h2>
<p><b>Author:</b>: <?php echo($author) ?></p>
<p><b>Categories: </b>: <?php echo($catList) ?></p>
</div>
<? php endforeach; ?>
</html>
[html]
再提一下,修改XML是較麻煩的。例如,添加一個(gè)目錄的代碼如下:
php:
[code]
function addCategory(DOMDocument $xml, $catID, $catName) {
$catName = $xml->createTextNode($catName); //創(chuàng)建一個(gè)結(jié)點(diǎn)以存儲(chǔ)文本
$category = $xml->createElement('category'); //創(chuàng)建一個(gè)目錄元素
$category->appendChild($catName); //把文本添加到目錄元素上
$category->setAttribute('cid', $catID); //設(shè)置目錄的ID
$XMLCategories = $xml->getElementsByTagName('categories')->item(0);
$XMLCategories->appendChild($category); //添加新目錄
}
五、 保存XML
你可以使用save()和saveXML()方法之一來(lái)把DOM描述轉(zhuǎn)換回XML字符串描述。save()方法用一指定的命名把XML保存到一個(gè)文件中,而saveXML()從文檔的部分或整體中返回一個(gè)字符串。
$xml->save('xml/library.xml');
//保存全部文件
$categories=$xml->saveXML($XMLCategories);
//返回一個(gè)包含種類的字符串
為了說(shuō)明把DOM兼容的代碼移植到另外的語(yǔ)言是如何容易,下面是用JavaScript形式實(shí)現(xiàn)的與以上功能相同的代碼:
Javascript:
復(fù)制代碼 代碼如下:
function doXML(){
/* 首先創(chuàng)建一個(gè)種類列表*/
var categories = Array();
var XMLCategories = xml.getElementsByTagName('categories')[0];
var theCategories = XMLCategories.getElementsByTagName('category');
for (var i = 0; i < theCategories.length; i++) {
/* 注意我們是怎樣得到屬性的*/
var cid = theCategories[i].getAttribute('cid');
categories[cid] = theCategories[i].firstChild.nodeValue;
}
var theBooks = xml.getElementsByTagName('book');
for(var i = 0; i < theBooks.length; i++) {
var book = theBooks[i];
/* 查找標(biāo)題*/
var title = book.getElementsByTagName('title')[0].firstChild.nodeValue;
/* 查找作者-為簡(jiǎn)單起見(jiàn),我們假定僅有一個(gè)作者*/
var author = book.getElementsByTagName('author')[0].firstChild.nodeValue;
/* 列出種類*/
var bookCategories = book.getElementsByTagName('category');
var catList = '';
for(var j = 0; j < bookCategories.length; j++) {
catList += categories[bookCategories[j].firstChild.nodeValue] + ', ';
}
catList = catList.substring(0, catList.length -2);
document.open();
document.write("<h2>" + title + "</h2>");
document.write("<p><b>Author:</b>: " + author + "</p>");
document.write("<p><b>Categories: </b>: " + catList + "</p>");
}
document.close();
}
六、 簡(jiǎn)單XML
簡(jiǎn)單XML確實(shí)簡(jiǎn)單。它允許使用對(duì)象和數(shù)組存取方法來(lái)存取一個(gè)XML文檔及其元素和屬性。操作方式很簡(jiǎn)單:
? 元素(Element)-這些被描述為SimpleXMLElement對(duì)象的單個(gè)屬性。當(dāng)有多個(gè)作為文檔或元素的子元素存在時(shí),每個(gè)元素能被使用數(shù)組索引標(biāo)志加以存取。
$xml->books;//返回元素"books"
$xml->books->book[0];//返回在books元素中的第一本書
? 屬性(Attribute)-元素的屬性是通過(guò)關(guān)聯(lián)數(shù)組標(biāo)志來(lái)存取和設(shè)置的,此時(shí)每一個(gè)索引對(duì)應(yīng)于一個(gè)屬性名。
$category['cid'];//返回cid屬性的值
? 元素?cái)?shù)據(jù)(Element Data)-為了檢索包含在一個(gè)元素內(nèi)的文本數(shù)據(jù),必須使用(string)顯式地把它被轉(zhuǎn)換為一個(gè)字符串或使用print或echo輸出它。如果一個(gè)元素包含多個(gè)文本結(jié)點(diǎn),那么它們將按被找到的順序連接起來(lái)。
echo ($xml->books->book[0]->title);//顯示第一本書的標(biāo)題
下面是使用簡(jiǎn)單XML進(jìn)行轉(zhuǎn)換的原來(lái)的實(shí)例。為了裝載XML文件,我們使用simplexml_load_file()函數(shù),由它來(lái)分析該XML文件并且把它裝載進(jìn)一個(gè)SimpleXMLElement對(duì)象中:
php:
復(fù)制代碼 代碼如下:
<?php
$xml = simplexml_load_file('xml/library.xml');
/* 把一個(gè)列表的目錄裝載到一個(gè)數(shù)組中*/
$categories = array();
foreach($xml->categories->category as $category) {
$categories[(string) $category['cid']] = (string) $category;
}
?>
<html>
<head>
<title>XML Library</title>
</head>
<body>
<?php foreach($xml->books->book as $book):
/* 列舉目錄*/
$catList = '';
foreach($book->category as $category) {
$catList .= $categories[((string) $category)] . ', ';
}
$catList = substr($catList, 0, -2); ?>
<div>
<h2><?php echo($book->title) ?></h2>
<p><b>Author:</b>: <?php echo($book->author) ?></p>
<p><b>Categories: </b>: <? php echo($catList) ?></p>
</div>
<? php endforeach; ?>
</html>
七、 修改XML
盡管文本數(shù)據(jù)和屬性值可以通過(guò)使用簡(jiǎn)單XML加以設(shè)置,但是不能新建這些對(duì)象。然而,SimpleXM的確提供了一種方法來(lái)實(shí)現(xiàn)DomElement對(duì)象和DomElement對(duì)象之間的轉(zhuǎn)換。為此,我修改了addCategory()函數(shù)來(lái)說(shuō)明如何使用simplexml_import_dom()函數(shù)以添加目錄和把該文檔轉(zhuǎn)換回簡(jiǎn)單的XML格式:
php:
復(fù)制代碼 代碼如下:
function addCategory(SimpleXMLElement &$sXML, $catID, $catName) {
$xml = new DOMDocument;
$xml->loadXML($sXML->asXML());
$catName = $xml->createTextNode($catName); //創(chuàng)建一個(gè)結(jié)點(diǎn)來(lái)存放該文本
$category = $xml->createElement('category'); //創(chuàng)建一個(gè)目錄元素
$category->appendChild($catName); //把文本添加到目錄元素
$category->setAttribute('cid', $catID); //設(shè)置目錄id
$XMLCategories = $xml->getElementsByTagName('categories')->item(0);
$XMLCategories->appendChild($category); //添加新目錄
$sXML = simplexml_import_dom($xml);
return $sXML;
}
同樣,SimpleXMLElement對(duì)象的asXML()函數(shù)可以用來(lái)檢索XML字符串并把它保存回一個(gè)文件中。
八、 xPath
毫無(wú)疑問(wèn),Xpath是"XML蛋糕之上的櫻桃"。XPath允許你使用象SQL一樣的查詢來(lái)查找一個(gè)XML文檔中的特定信息。DOM和SimpleXML都有內(nèi)置的對(duì)XPath的支持,如SQL,可以被用來(lái)提取你想從一XML文檔中提取的任何內(nèi)容。
程序代碼
? //category-查找所有的在文檔中出現(xiàn)的任何category。
? /library/books-查找所有作為library的孩子出現(xiàn)的books
? /library/categories/category[@cid]-查找所有作為library/categories的孩子出現(xiàn)且屬性為cid的category。
? /library/categories/category[@att='2']-查找所有作為library/categories的孩子且具有屬性cid的值為2出現(xiàn)的category。
? /library/books/book[title='Apache 2']-查找所有作為/library/books的孩子且其標(biāo)題元素有一個(gè)值為Apache 2出現(xiàn)的book。
其實(shí),這僅是xPath冰山之一角。你可以使用xPath來(lái)創(chuàng)建大量復(fù)雜的查詢以便從你的文檔中提取幾乎任何信息。我再次修改了示例代碼來(lái)向你展示使用xPath是多么輕松愉快的事情。
php:
復(fù)制代碼 代碼如下:
<?php
$xml = simplexml_load_file('xml/library.xml');
?>
<html>
<head>
<title>XML Library</title>
</head>
<body>
<?php foreach(((array)$xml->xpath("/library/books/book")) as $book):
/*列表目錄*/
$catList = '';
foreach($book->category as $category) {
/*得到具有這個(gè)ID的目錄*/
$category = $xml->xpath("/library/categories/category[@cid='$category']");
$catList .= (string) $category[0] . ', ';
}
$catList = substr($catList, 0, -2); ?>
<div>
<h2><?php echo($book->title) ?></h2>
<p><b>Author:</b>: <?php echo($book->author) ?></p>
<p><b>Categories: </b>: <?php echo($catList) ?></p>
</div>
<?php endforeach; ?>
</html>
九、 DOM和XPath
在DOM中計(jì)算XPath查詢需要?jiǎng)?chuàng)建一個(gè)DOMXPath對(duì)象,下面的evaluate()函數(shù)返回一個(gè)DOMElement數(shù)組。
復(fù)制代碼 代碼如下:
$xPath = new DOMXPath($xml);
$xPath->evaluate("/library/books/book[title='Apache 2']");
十、 結(jié)論
現(xiàn)在,我們學(xué)習(xí)了如何使用了php提供給我們的工具來(lái)與XML交互。至此,我們已經(jīng)被"武裝起來(lái)"并準(zhǔn)備好深入鉆研XML應(yīng)用程序了。在下一篇文章中,我們將討論AJAX及其如何應(yīng)用于象Google這樣的站點(diǎn)開(kāi)發(fā)的。
php技術(shù):PHP中開(kāi)發(fā)XML應(yīng)用程序之基礎(chǔ)篇 添加節(jié)點(diǎn) 刪除節(jié)點(diǎn) 查詢節(jié)點(diǎn) 查詢節(jié),轉(zhuǎn)載需保留來(lái)源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。