PHP操作XML詳解
XML是一種流行的半結構化檔案格式,以一種類似資料庫的格式儲存資料。在實際應用中,一些簡單的、安全性較低的資料往往使用 XML檔案的格式進行儲存。這樣做的好處一方面可以通過減少與資料庫的互動性操作提高讀取效率,另一方面可以有效利用 XML的優越性降低程式的編寫難度。
PHP提供了一整套的讀取 XML檔案的方法,很容易的就可以編寫基於 XML的指令碼程式。本章將要介紹 PHP與 XML的操作方法,並對幾個常用的 XML類庫做一些簡要介紹。
1 XML簡介
XML是“可擴充套件性標識語言(eXtensible Markup Language)”的縮寫,是一種類似於 HTML的標記性語言。但是與 HTML不同,XML主要用於描述資料和存放資料,而 HTML主要用於顯示資料。
- <thread>
- <title>Welcome</title>
- <author>Simon</author>
- <content>Welcome to XML guestbook!!</content>
- </thread>
其中,<thread>與</thread>標籤標記了這是一段留言。在留言中有標題、作者、內容,完整的表述了一條留言資訊。
圖片:1.jpg
XML的發展非常迅速,近些年來很多軟體開發商都開始採用 XML的開發標準進行應用程式的開發。並且,很多新興技術都架構在 XML資料之上。這意味著 XML將與 HTML一樣成為 Web技術不可或缺的一部分。
2 簡單的 XML操作
在實際應用中,PHP與 XML的互動操作應用非常廣泛。SimpleXML元件是 PHP5新增加的一個簡
單的 XML操作元件,與傳統的 XML元件相比,SimpleXML元件的使用非常簡單。本節將對使用
2.1 建立一個 SimpleXML物件
SimpleXML物件是用來臨時儲存 XML資料的臨時變數,對 XML進行的操作都是通過操作 SimpleXML物件來完成的。SimpleXML元件提供了兩種建立 SimpleXML物件的方法。第一種方法是使用 simplexml_load_string函式讀取一個字串型變數中的 XML資料來完成建立的,其語法格式如下所示。
simplexml_load_string(string data)
這裡的 data變數用於儲存 XML資料。以下程式碼使用 simplexml_load_string函式建立了一個 SimpleXML物件 複製程式碼
- <hr><?php
- $data = <<<XML //定義 XML資料
- <?xml version=’1.0′?>
- <departs>
- <depart>
- <name>production support</name>
- <employees>
- <employee>
- <serial_no>100001</serial_no>
- <name>Simon</name>
- <age>24</age>
- <birthday>1982-11-06</birthday>
- <salary>5000.00</salary>
- <bonus>1000.00</bonus>
- </employee>
- <employee>
- <serial_no>100002</serial_no>
- <name>Elaine</name>
- <age>24</age>
- <birthday>1982-01-01</birthday>
- <salary>6000.00</salary>
- <bonus>2000.00</bonus>
- </employee>
- </employees>
- </depart>
- <depart>
- <name>testing center</name>
- <employees>
- <employee>
- <serial_no>110001</serial_no>
- <name>Helen</name>
- <age>23</age>
- <birthday>1983-07-21</birthday>
- <salary>5000.00</salary>
- <bonus>1000.00</bonus>
- </employee>
- </employees>
- </depart>
- </departs>
- XML;
- $xml = simplexml_load_string($data); //建立 SimpleXML物件
- print_r($xml); //輸出 XML
- ?><hr>
在上面的例子中,$data變數儲存了一段 XML資料。 simplexml_load_string函式將變數$data轉化成 SimpleXML物件。通過 print_r函式的輸出可以看出該物件的結構,執行結果如下所示。
複製程式碼- SimpleXMLElement Object
- (
- [depart] => Array
- (
- [0] => SimpleXMLElement Object
- (
- [name] => production support
- [employees] => SimpleXMLElement Object
- ([employee] => Array (
- [0] => SimpleXMLElement Object
- ( [serial_no] => 100001
- [name] => Simon
- [age] => 24
- [birthday] => 1982-11-06
- [salary] => 5000.00
- [bonus] => 1000.00
- )
- [1] => SimpleXMLElement Object
- ( [serial_no] => 100002
- [name] => Elaine
- [age] => 24
- [birthday] => 1982-01-01
- [salary] => 6000.00
- [bonus] => 2000.00
- )
- )
- )
- )
- [1] => SimpleXMLElement Object
- (
- [name] => testing center
- [employees] => SimpleXMLElement Object
- (
- [employee] => SimpleXMLElement Object
- (
- [serial_no] => 110001
- [name] => Helen
- [age] => 23
- [birthday] => 1983-07-21
- [salary] => 5000.00
- [bonus] => 1000.00
- )
- )
- )
- )
- )
從輸出結果可以看出,SimpleXML物件的結構與 XML資料的格式完全相同。
第二種方法是使用 simplexml_load_flie函式讀取一個 XML檔案來完成建立的,其語法格式如下所示。
simplexml_load_file(string filename)
這裡的 filename變數是用於儲存 XML資料檔案的檔名及其所在路徑。以下程式碼使用 simplexml_load_file函式來建立了一個 SimpleXML物件。
- <?php
- $xml = simplexml_load_file(’example.xml’); //建立 SimpleXML物件
- print_r($xml); //輸出 XML
- ?>
其中,example.xml儲存的資料與上面的$data完全相同,執行結果也與上面完全相同。
上面兩種方法實現了同樣的功能,其區別就在於 XML的資料來源不同。如果 XML的資料來源在 PHP指令碼檔案中,則需要使用 simplexml_load_string來進行建立。如果 XML的資料來源在一個單獨的 XML檔案中,則需要使用 simplexml_load_file來進行建立。
2.2 讀取 SimpleXML物件中的 XML資料
前面介紹了使用 print_r函式來讀取 SimpleXML物件中的資料,其返回結果與陣列的結構類似。顯然,這種顯示方式在實際應用中是不可取的。在這裡將介紹其他的幾種讀取 SimpleXML物件中 XML資料的方法。
1.var_dump函式顯示物件詳細資訊
var_dump函式可以用於顯示 SimpleXML物件的詳細資訊,與 print_r函式相比,var_dump函式顯示的資訊更為完整,其語法如下所示。
void var_dump(object1, object2 … )
以下程式碼使用 var_dump函式輸出了上面例子中物件的詳細資訊。
- <?php $xml = simplexml_load_file(’example.xml’); //建立 SimpleXML物件 var_dump($xml); //輸出 XML
- ?>
執行結果如下所示。
複製程式碼- object(SimpleXMLElement)#1 (1) { ["depart"]=>array(2) {
- [0]=>
- object(SimpleXMLElement)#2 (2) {
- ["name"]=>
- string(18) “production support”
- ["employees"]=>
- object(SimpleXMLElement)#4 (1) {
- ["employee"]=>
- array(2) {
- [0]=>
- object(SimpleXMLElement)#5 (6) {
- ["serial_no"]=>
- string(6) “100001″
- ["name"]=>
- string(5) “Simon”
- ["age"]=>
- string(2) “24″
- ["birthday"]=>
- string(10) “1982-11-06″
- ["salary"]=>
- string(7) “5000.00″
- ["bonus"]=>
- string(7) “1000.00″
- }
- [1]=>
- object(SimpleXMLElement)#6 (6) {
- ["serial_no"]=>
- string(6) “100002″
- ["name"]=>
- string(6) “Elaine”
- ["age"]=>
- string(2) “24″
- ["birthday"]=>
- string(10) “1982-01-01″
- ["salary"]=>
- string(7) “6000.00″
- ["bonus"]=>
- string(7) “2000.00″
- }
- }
- }
- }
- [1]=>
- object(SimpleXMLElement)#3 (2) {
- ["name"]=>
- string(14) “testing center”
- ["employees"]=>
- object(SimpleXMLElement)#7 (1) {
- ["employee"]=>
- object(SimpleXMLElement)#8 (6) {
- ["serial_no"]=>
- string(6) “110001″
- ["name"]=>
- string(5) “Helen”
- ["age"]=>
- string(2) “23″
- ["birthday"]=>
- string(10) “1983-07-21″
- ["salary"]=>
- string(7) “5000.00″
- ["bonus"]=>
- string(7) “1000.00″
- }
- }
- }
- }
- }
與前面 print_r輸出的結果相比較,var_dump函式的輸出結果的結構更為嚴謹,並且將物件中的每一個屬性的資料型別均作出分析。在實際應用中,var_dump函式往往用於程式除錯時的物件檢測。
2.讀取 XML資料中的標籤
與運算元組型別的變數類似,讀取 XML也可以通過類似的方法來完成。例如,如果需要讀取上面 XML資料中每一個“ depart”標籤下的“name”屬性,可以通過使用 foreach函式來完成,如以下程式碼
所示。
- <?php $xml = simplexml_load_file(’example.xml’); foreach($xml->depart as $a)
- {
- echo “$a->name <BR>”;
- }
- ?>
執行結果如下所示。
production support
testing center
//讀取 XML檔案 //迴圈讀取 XML資料中的每一個 depart標籤
//輸出其中的 name屬性
也可以使用方括號“ []”來直接讀取 XML資料中指定的標籤。以下程式碼輸出了上面 XML資料中的第一個“depart”標籤的“name”屬性。
- <?php
- $xml = simplexml_load_file(’example.xml’); //讀取 XML檔案
- echo $xml->depart->name[0]; //輸出節點
- ?>
執行結果如下所示。
production support
對於一個標籤下的所有子標籤,SimpleXML元件提供了 children方法進行讀取。例如,對於上面的 XML資料中的“ depart”標籤,其下包括兩個子標籤:“ name”和“employees”。以下程式碼實現了對第一個“depart”標籤下的子標籤的讀取。
- <?php
- $xml = simplexml_load_file(’example.xml’);
- foreach ($xml->depart->children() as $depart) //迴圈讀取 depart標籤下的子標籤
- {
- var_dump($depart); //輸出標籤的 XML資料
- }
- ?>
執行結果如下所示。
複製程式碼- object(SimpleXMLElement)#3 (1) {
- [0]=>
- string(18) “production support”
- }
- object(SimpleXMLElement)#5 (1) {
- ["employee"]=>
- array(2) {
- [0]=>
- object(SimpleXMLElement)#3 (6) {
- ["serial_no"]=>
- string(6) “100001″
- ["name"]=>
- string(5) “Simon”
- ["age"]=>
- string(2) “24″
- ["birthday"]=>
- string(10) “1982-11-06″
- ["salary"]=>
- string(7) “5000.00″
- ["bonus"]=>
- string(7) “1000.00″
- }
- [1]=>
- object(SimpleXMLElement)#6 (6) {
- ["serial_no"]=>
- string(6) “100002″
- ["name"]=>
- string(6) “Elaine”
- ["age"]=>
- string(2) “24″
- ["birthday"]=>
- string(10) “1982-01-01″
- ["salary"]=>
- string(7) “6000.00″
- ["bonus"]=>
- string(7) “2000.00″
- }
- }
- }
可以看出,使用 children方法後,所有的子標籤均被當作一個新的 XML檔案進行處理。
3.基於 XML資料路徑的查詢
SimpleXML元件提供了一種基於 XML資料路徑的查詢方法。 XML資料路徑即從 XML的根到某一個標籤所經過的全部標籤。這種路徑使用斜線“ /”隔開標籤名。例如,對於上面的 XML資料,要查詢所有的標籤“name”中的值,從根開始要經過 departs、depart、employees和 employee標籤,則其路徑
為“/departs/depart/employees/employee/name”。 SimpleXML元件使用 xpath方法來解析路徑,其語法格式如下所示。
xpath(string path)
其中的 path為路徑。該方法返回了一個包含有所有要查詢標籤值的陣列。以下程式碼查詢了上面 XML資料中的所有 name標籤。
- <?php
- $xml = simplexml_load_file(’example.xml’); //讀取 XML檔案
- $result = $xml->xpath(’/departs/depart/employees/employee/name’);//定義節點
- var_dump($result); //輸出節點
- ?>
執行結果如下所示。
複製程式碼- array(3) {
- [0]=> object(SimpleXMLElement)#2 (1) {
- [0]=> string(5) “Simon”
- }
- [1]=>object(SimpleXMLElement)#3 (1) {
- [0]=> string(6) “Elaine”
- }
- [2]=>object(SimpleXMLElement)#4 (1) {
- [0]=> string(5) “Helen”
- }
- }
可以看出,所有的 name標籤均被查詢出來。
2.3 XML資料的修改
對於 XML資料的修改與讀取 XML資料中的標籤方法類似。即通過直接修改 SimpleXML物件中的標籤的值來實現。以下程式碼實現了對上面 XML資料中第一個“ depart”標籤的“ name”子標籤的修改。
- <?php
- $xml = simplexml_load_file(’example.xml’); //讀取 XML
- $xml->depart->name[0] = “Human Resource”; //修改節點
- ?>
修改後,並不會對 XML檔案有任何影響。但是,在程式中,對於 SimpleXML物件的讀取將使用修改過的值。
2.4 標準化 XML資料
SimpleXML還提供了一種標準化 XML資料的方法 asXML。asXML方法可以有效的將 SimpleXML物件中的內容按照 XML 1.0標準進行重新編排並以字串的資料型別返回。以下程式碼實現了對上面 XML資料的標準化。
- <?php
- $xml = simplexml_load_file(’example.xml’); //讀取 XML資料
- echo $xml->asXML(); //標準化 XML資料
- ?>
2.5 XML資料的儲存
將 SimpleXML物件中的 XML資料儲存到一個 XML檔案的方法非常簡單,即將 asXML方法的返回結果輸出到一個檔案中即可。以下程式碼首先將 XML檔案中的 depart name進行了修改,然後將修改過的 XML資料輸出到另一個 XML檔案。
- <?php
- $xml = simplexml_load_file(’example.xml’); //讀取 XML資料
- $newxml = $xml->asXML(); //標準化 XML資料
- $fp = fopen(”newxml.xml”, “w”); //開啟要寫入 XML資料的檔案
- fwrite($fp, $newxml); //寫入 XML資料
- fclose($fp); //關閉檔案
- ?>
程式碼執行後,可以看到在 newxml.xml檔案中的 XML資料如下所示。
複製程式碼- <?xml version=”1.0″?>
- <departs>
- <depart>
- <name>Human Resource</name>
- <employees>
- <employee>
- <serial_no>100001</serial_no>
- <name>Simon</name>
- <age>24</age>
- <birthday>1982-11-06</birthday>
- <salary>5000.00</salary>
- <bonus>1000.00</bonus>
- </employee>
- <employee>
- <serial_no>100002</serial_no>
- <name>Elaine</name>
- <age>24</age>
- <birthday>1982-01-01</birthday>
- <salary>6000.00</salary>
- <bonus>2000.00</bonus>
- </employee>
- </employees>
- </depart>
- <depart>
- <name>testing center</name>
- <employees>
- <employee>
- <serial_no>110001</serial_no>
- <name>Helen</name>
- <age>23</age>
- <birthday>1983-07-21</birthday>
- <salary>5000.00</salary>
- <bonus>1000.00</bonus>
- </employee>
- </employees>
- </depart>
- </departs>
可以看出,對於 XML檔案的修改已經儲存到輸出檔案中了。
3 XML文件的動態建立
在實際應用中,時而會需要動態生成 XML文件的操作。前面介紹的 SimpleXML元件並不提供建立 XML文件的方法。因此,如果需要動態建立 XML文件,往往使用 DOM元件進行建立。 DOM是文件物件模型 Document Object Model的縮寫, DOM元件提供了對 XML文件的樹型解析模式。以下程式碼使用 DOM元件建立了一個 XML文件。
- <?php
- //建立一個新的 DOM文件
- $dom = new DomDocument();
- //在根節點建立 departs標籤
- $departs = $dom->createElement(’departs’);
- $dom->appendChild($departs);
- //在 departs標籤下建立 depart子標籤
- $depart = $dom->createElement(’depart’);
- $departs->appendChild($depart);
- //在 depart標籤下建立 employees子標籤
- $employees = $dom->createElement(’employees’);
- $depart->appendChild($employees);
- //在 employees標籤下建立 employee子標籤
- $employee = $dom->createElement(’employee’);
- $employees->appendChild($employee);
- //在 employee標籤下建立 serial_no子標籤
- $serial_no = $dom->createElement(’serial_no’);
- $employee->appendChild($serial_no);
- //為 serial_no標籤新增值節點 100001
- $serial_no_value = $dom->createTextNode(’100001′);
- $serial_no->appendChild($serial_no_value);
- //輸出 XML資料
- echo $dom->saveXML();
- ?>
- 輸出結果如下所示。
- <?xml version=”1.0″?>
- <departs>
- <depart>
- <employees>
- <employee>
- <serial_no>100001</serial_no>
- </employee>
- </employees>
- </depart>
- </departs>
DOM元件除了可以用來動態建立 XML文件外,還可以用來讀取 XML檔案。以下程式碼實現了對前
面 XML檔案的讀取。
- <?php
- $dom = new DomDocument();//建立 DOM物件
- $dom->load(’example.xml’);//讀取 XML檔案
- $root = $dom->documentElement;//獲取 XML資料的根
- read_child($root);//呼叫 read_child函式讀取根物件
- function read_child($node)
- {
- $children = $node->childNodes;//獲得$node的所有子節點
- foreach($children as $e)//迴圈讀取每一個子節點
- {
- if($e->nodeType == XML_TEXT_NODE) //如果子節點為文字型則輸出
- {
- echo $e->nodeValue.”<BR>”;
- }
- else if($e->nodeType == XML_ELEMENT_NODE) //如果子節點為節點物件,則呼叫函式處理
- {
- read_child($e);
- }
- }
- }
- ?>
執行結果如下所示。
引用 production support
100001
Simon
24
1982-11-06
5000.00
1000.00
100002
Elaine
24
1982-01-01
6000.00
2000.00
testing center
110001
Helen
23
1983-07-21
5000.00
1000.00
上面的例子使用了遞迴的方式對 XML資料進行了處理,實現了輸出 XML資料中的所有文字型標籤的功能。
4 XML應用例項——留言本
前面介紹了 XML的基本操作,本節將以設計一個 XML留言本為例來詳細說明在實際應用中如何實現 PHP與 XML資料的互動操作。
4.1 XML檔案結構設計
XML檔案用於儲存 XML資料,也就是留言本中的留言。這裡,對於每條留言,在 XML資料中主要包括三項內容:留言標題、留言者姓名、留言內容。因此,將 XML檔案的格式設計如下。
- <?xml version=”1.0″?>
- <threads>
- <thread>
- <title>這裡是留言的標題</title>
- <author>這裡是留言者</author>
- <content>這裡是留言內容</content>
- </thread>
- </threads>
4.2 提交頁面的編寫
提交留言頁面由兩個頁面組成。一個是讓訪問者用來書寫留言的表單的 HTML檔案,一個是用來處理訪問者輸入的 PHP指令碼。表單的 HTML程式碼如下所示。
- <html>
- <head>
- <title>發表新的留言</title>
- <meta http-equiv=”Content-Type” content=”text/html; charset=gb2312″>
- </head>
- <body>
- <H1><p align=”center”>發表新的留言</p></H1>
- <form name=”form1″ method=”post” action=”Post.php”>
- <table width=”500″ border=”0″ align=”center” cellpadding=”0″ cellspacing=”0″>
- <tr>
- <td>標題</td>
- <td><input name=”title” type=”text” id=”title” size=”50″></td>
- </tr>
- <tr>
- <td>作者</td>
- <td><input name=”author” type=”text” id=”author” size=”20″></td>
- </tr>
- <tr>
- <td>內容</td>
- <td><textarea name=”content” cols=”50″ rows=”10″ id=”content”></textarea></td>
- </tr>
- </table>
- <p align=”center”>
- <input type=”submit” value=”Submit”>
- <input type=”reset” value=”Reset”>
- </p>
- </form>
- </body>
- </html>
對於用來處理使用者輸入的 PHP指令碼,其基本邏輯是首先建立一個 DOM物件,然後讀取 XML檔案中的 XML資料,接下來在 XML物件上建立新的節點並將使用者的輸入儲存起來,最後將 XML資料輸出到原來的 XML檔案中。具體實現程式碼如下所示。
複製程式碼- <?php
- $guestbook = new DomDocument(); //建立一個新的 DOM物件
- $guestbook->load(’DB/guestbook.xml’); //讀取 XML資料
- $threads = $guestbook->documentElement; //獲得 XML結構的根
- //建立一個新 thread節點
- $thread = $guestbook->createElement(’thread’);
- $threads->appendChild($thread);
- //在新的 thread節點上建立 title標籤
- $title = $guestbook->createElement(’title’);
- $title->appendChild($guestbook->createTextNode($_POST['title']));
- $thread->appendChild($title);
- //在新的 thread節點上建立 author標籤
- $author = $guestbook->createElement(’author’);
- $author->appendChild($guestbook->createTextNode($_POST['author']));
- $thread->appendChild($author);
- //在新的 thread節點上建立 content標籤
- $content = $guestbook->createElement(’content’);
- $content->appendChild($guestbook->createTextNode($_POST['content']));
- $thread->appendChild($content);
- //將 XML資料寫入檔案
- $fp = fopen(”DB/guestbook.xml”, “w”);
- if(fwrite($fp, $guestbook->saveXML()))
- echo “留言提交成功”;
- else
- echo “留言提交失敗”;
- fclose($fp);
- ?>
在瀏覽器中執行上述 HTML檔案並填寫適當的留言內容,如圖 2所示。
圖片:2.jpg
圖 2 發表新留言介面
單擊【Submit】按鈕後,XML檔案中的內容如下所示。
- <?xml version=”1.0″?>
- <threads>
- <thread>
- <title>Welcome</title>
- <author>Simon</author>
- <content>Welcome to XML guestbook!!</content>
- </thread>
- </threads>
可以看到 XML檔案中已經將留言儲存起來了。
4.3 顯示頁面的編寫
顯示頁面可以使用前面介紹的 SimpleXML元件很容易的實現,具體實現程式碼如下所示。
- <?php
- //開啟用於儲存留言的 XML檔案
- $guestbook = simplexml_load_file(’DB/guestbook.xml’);
- foreach($guestbook->thread as $th) //迴圈讀取 XML資料中的每一個 thread標籤
- {
- echo “<B>標題:</B>”.$th->title.”<BR>”;
- echo “<B>作者:</B>”.$th->author.”<BR>”;
- echo “<B>內容:</B><PRE>”.$th->content.”</PRE>”;
- echo “<HR>”;
- }
- ?>
在瀏覽器中檢視執行結果如圖 3所示。
圖片:3.jpg
源自:http://www.oicto.com/php-xml/
轉載於:https://my.oschina.net/deacyn/blog/135810