一、 XML簡介
XML(可擴充的標註語言)是一種W3C標準,主要用於Web應用程式和伺服器之間實現容易的互動、資料的儲存與使用。
使用XML標準編碼的資料具有能容易被人和電腦解釋的意義和結構。XML資料是平台和應用程式獨立的。不用多說,這本身就使XML成為適合於互連網的一個理想的資料交換格式(事實上,它正是因這一用途而被開發的)。最近,寬頻連線的增長及消費者對于越過任何媒體進行資料共用的應用軟體的需求意味著,XML Web服務和應用軟體正變得越來越豐富。
XML的發明正是為瞭解決描述網上豐富的資料的組織問題;而目前為止,這一問題僅能夠通過HTML的巧妙使用得到部分地解決。
下面是一XML文檔的執行個體:
程式碼 複製代碼 代碼如下:<?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>
如果你以前沒見過XML,那麼你可以認為它看起來象HTML。HTML是一種SGML應用程式,而XML是它的一個子集。然而,其相似性還包括它們具有相似的標註分隔字元。
僅需看一下上面的XML片斷,我們就能看到,該資料是描述一個具有一些客人的聚會;其中,每一個客人相應於一項。用於描述資料的標籤名完全由作者來選擇。所有XML標準要求:資料必須是一致的並且用於描述資料的標籤為良構的。我們可以進一步用一種文件類型聲明(DTD)或一個XML模式來強制資料的完整性。然而為簡化起見,我們在本文中將僅使用普通的XML。
二、 XML應用程式
剛才,我們已經看到了如何使用XML來描述任何種類的資料。事實上,XML已經在今天的許多Web應用程式中得到廣泛使用,下面是一些著名的應用描述:
· XHTML-這是使用最廣泛的XML應用程式之一。它類似基於HTML的SGML-用於描述資料在網頁上的顯示方式。XHTML使用一DTD來確保所有的文檔遵循標準。XHTML的出現使Web程式員的開發稍微容易了一些;然而,一種完全相容於CSS和XHTML標準的web瀏覽器尚未出現。
· XML-RPC-遠端程序呼叫(RPC),應用於分布式應用程式中以調用遠端電腦上的過程。XML-RPC使用XML對關於程序呼叫的資訊進行編碼,並且使用HTTP把它發送到接收電腦。然後,過程的傳回值被再次用XML編碼並用HTTP串連發送回調用者電腦。
· RSS-真正簡單的彙總/豐富的網站摘要,它是一種用來彙總web網站內容(例如新聞、文章、共用價格和連結等)的方法,它用一個特殊的應用程式(一個彙總器)定期更新使用者PC上的RSS回饋。該RSS資料是使用XML進行編碼和傳輸的。
· AJAX-非同步JavaScript和XML,允許web開發人員建立具有豐富特徵的事件驅動的運行在web瀏覽器上的web應用程式。其中,JavaScript用於把XML編碼的資料發送到伺服器端指令碼(或從伺服器端接收XML編碼的資料),並允許局部的即時的頁面更新而不需要更新所有頁面內容。
上面僅僅是XML的可能的應用的一部分。在以後文章中,我們將分析如何在PHP中使用這些應用軟體。
三、 在PHP中使用XML
自從PHP 5.0以來,PHP能與XML互動的可用選項顯著地增加。而PHP版本4所能提供的是不穩定的而且是非w3c相容的DOM XML擴充。
下面,我將集中討論PHP 5所提供給我們的三個允許我們與XML互動的方法:DOM,簡單XML和XPath。在可能之處,我將建議最適合於每種方法的條件和資料。所有的範例程式碼將使用XML資料來源來描述一個庫及其中包含的書。
程式碼 複製代碼 代碼如下:<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副檔名允許使用W3C DOM API在XML文檔上進行操作。在PHP 5出現之前,這是PHP能存取XML文檔的唯一方法。如果你在JavaScript中使用了DOM,那麼會認識到這些物件模型幾乎是一樣的。
由於DOM方法在遍曆和操作XML文檔時比較羅嗦,所以任何DOM相容的代碼都有明顯的優點-與任何其它實現相同的W3C相容的物件模型的API相容。
在下面的執行個體代碼中,我們使用DOM來顯示關於每本書的資訊。首先,我們遍曆一下列表目錄,把它們的Id和相應的名字裝載到一個索引數組中。然後,我們顯示每本書的一個簡短描述:
PHP: 複製代碼 代碼如下:<?php
/*這裡我們必須指定XML版本:也即是1.0 */
$xml = new DomDocument('1.0');
$xml->load('xml/library.xml');
/*首先,建立一個目錄列表*/
$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):
/*尋找標題*/
$title = $book->getElementsByTagName('title')->item(0)->firstChild->nodeValue;
/*尋找作者-為了簡化起見,我們假設僅僅有一個作者*/
$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是較麻煩的。例如,添加一個目錄的代碼如下:
PHP:
[code]
function addCategory(DOMDocument $xml, $catID, $catName) {
$catName = $xml->createTextNode($catName); //建立一個結點以儲存文本
$category = $xml->createElement('category'); //建立一個目錄元素
$category->appendChild($catName); //把文本添加到目錄元素上
$category->setAttribute('cid', $catID); //設定目錄的ID
$XMLCategories = $xml->getElementsByTagName('categories')->item(0);
$XMLCategories->appendChild($category); //添加新目錄
}
五、 儲存XML
你可以使用save()和saveXML()方法之一來把DOM描述轉換回XML字串描述。save()方法用一指定的命名把XML儲存到一個檔案中,而saveXML()從文檔的部分或整體中返回一個字串。
$xml->save('xml/library.xml');
//儲存全部檔案
$categories=$xml->saveXML($XMLCategories);
//返回一個包含種類的字串
為了說明把DOM相容的代碼移植到另外的語言是如何容易,下面是用JavaScript形式實現的與以上功能相同的代碼:
Javascript: 複製代碼 代碼如下:function doXML(){
/* 首先建立一個種類列表*/
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];
/* 尋找標題*/
var title = book.getElementsByTagName('title')[0].firstChild.nodeValue;
/* 尋找作者-為簡單起見,我們假定僅有一個作者*/
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();
}
六、 簡單XML
簡單XML確實簡單。它允許使用對象和數組存取方法來存取一個XML文檔及其元素和屬性。操作方式很簡單:
· 元素(Element)-這些被描述為SimpleXMLElement對象的單個屬性。當有多個作為文檔或元素的子項目存在時,每個元素能被使用數組索引標誌加以存取。
$xml->books;//返回元素"books"
$xml->books->book[0];//返回在books元素中的第一本書
· 屬性(Attribute)-元素的屬性是通過關聯陣列標誌來存取和設定的,此時每一個索引對應於一個屬性名稱。
$category['cid'];//返回cid屬性的值
· 元素資料(Element Data)-為了檢索包含在一個元素內的文本資料,必須使用(string)顯式地把它被轉換為一個字串或使用print或echo輸出它。如果一個元素包含多個文本結點,那麼它們將按被找到的順序串連起來。
echo ($xml->books->book[0]->title);//顯示第一本書的標題
下面是使用簡單XML進行轉換的原來的執行個體。為了裝載XML檔案,我們使用simplexml_load_file()函數,由它來分析該XML檔案並且把它裝載進一個SimpleXMLElement對象中:
PHP: 複製代碼 代碼如下:<?php
$xml = simplexml_load_file('xml/library.xml');
/* 把一個列表的目錄裝載到一個數組中*/
$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
儘管文本資料和屬性值可以通過使用簡單XML加以設定,但是不能建立這些對象。然而,SimpleXM的確提供了一種方法來實現DomElement對象和DomElement對象之間的轉換。為此,我修改了addCategory()函數來說明如何使用simplexml_import_dom()函數以添加目錄和把該文檔轉換回簡單的XML格式:
PHP: 複製代碼 代碼如下:function addCategory(SimpleXMLElement &$sXML, $catID, $catName) {
$xml = new DOMDocument;
$xml->loadXML($sXML->asXML());
$catName = $xml->createTextNode($catName); //建立一個結點來存放該文本
$category = $xml->createElement('category'); //建立一個目錄元素
$category->appendChild($catName); //把文本添加到目錄元素
$category->setAttribute('cid', $catID); //設定目錄id
$XMLCategories = $xml->getElementsByTagName('categories')->item(0);
$XMLCategories->appendChild($category); //添加新目錄
$sXML = simplexml_import_dom($xml);
return $sXML;
}
同樣,SimpleXMLElement對象的asXML()函數可以用來檢索XML字串並把它儲存回一個檔案中。
八、 xPath
毫無疑問,Xpath是"XML蛋糕之上的櫻桃"。XPath允許你使用象SQL一樣的查詢來尋找一個XML文檔中的特定資訊。DOM和SimpleXML都有內建的對XPath的支援,如SQL,可以被用來提取你想從一XML文檔中提取的任何內容。
程式碼
· //category-尋找所有的在文檔中出現的任何category。
· /library/books-尋找所有作為library的孩子出現的books
· /library/categories/category[@cid]-尋找所有作為library/categories的孩子出現且屬性為cid的category。
· /library/categories/category[@att='2']-尋找所有作為library/categories的孩子且具有屬性cid的值為2出現的category。
· /library/books/book[title='Apache 2']-尋找所有作為/library/books的孩子且其標題元素有一個值為Apache 2出現的book。
其實,這僅是xPath冰山之一角。你可以使用xPath來建立大量複雜的查詢以便從你的文檔中提取幾乎任何資訊。我再次修改了範例程式碼來向你展示使用xPath是多麼輕鬆愉快的事情。
PHP: 複製代碼 代碼如下:<?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) {
/*得到具有這個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中計算XPath查詢需要建立一個DOMXPath對象,下面的evaluate()函數返回一個DOMElement數組。 複製代碼 代碼如下:$xPath = new DOMXPath($xml);
$xPath->evaluate("/library/books/book[title='Apache 2']");
十、 結論
現在,我們學習了如何使用了PHP提供給我們的工具來與XML互動。至此,我們已經被"武裝起來"並準備好深入鑽研XML應用程式了。在下一篇文章中,我們將討論AJAX及其如何應用於象Google這樣的網站開發的。