2007年04月10日

A note of creating XML document by SimpleXML

php xml spreadsheet simplexml

本文嚐試利用 PHP5 提供的 SimpleXML 函數組 ,建立一份可供 MS Excel 2000/XP 版本使用的 XML 文件。

需求起因於資料庫之資料匯出需求。以往大都採用 CSV 格式匯出,然而 CSV 文件用於保存 Big5 內碼編碼之資料時水土不服,容易發生分欄錯誤之情況。儘管我們將字元編碼改為 UTF-8 後便可避免此問題,但是卻又面臨 MS Excel 2000/XP 無法以正確之字元編碼讀取 CSV 文件的窘境。因此我需要一個可為 OpenOffice 以及 MS Excel 2000/XP 兩者共同辨識的資料格式。經我測試後,確認 MS Excel 2000/XP 之 XML 試算表格式符合此需求。


接下來將以 MS Excel 2000/XP 之 XML 格式為準,撰寫一個以 SimpleXML 建立 XML 文件的測試程式,並說明 SimpleXML 之部份使用事項。

下例是 MS Excel 2000/XP 最基本的 XML 試算表範例:

試算表中的工作表元素由 <Worksheet><Table> 組成,其中 <Worksheet> 必須具備屬性 ss:Name。工作表之下為「列(<Row>)」,列之下為「儲存格(<Cell>)」。

下列為利用 SimpleXML 建立 XML 文件的測試程式。

首先,我提供一份空白試算表的 XML 內容給 SimpleXMLElement 建立最本的 SimpleXML 文件結構。$doc 便指向此文件之根節點 <Workbook> 。接著我以 addChild() 在根節點之下添加子節點 <Worksheet>

由於 <Worksheet> 必須具有屬性 ss:Name ,所以我接下來嚐試以 addAttribute()<Worksheet> 設定屬性。然而此時我碰到了一個疑似 bug 的狀況。除了 addAttribute() 外,我們也可以透過陣列索引子,以 setter 直接增加新屬性。通常以 setter 直接設定新屬性之方式與 addAttribute() 之效果相同,但對於屬性名稱結合名稱空間之處理方式有所差異(Maybe a bug of addAttribute())。在此例中(attribute with namespace), addAttribute() 會忽略屬性名稱的名稱空間 'ss',故其輸出之 XMLString 的 <Worksheet> 之屬性名稱為 Type 而非 ss:Type。但以 setter 設定時,則可忠實保留屬性名稱及名稱空間。故我接下來皆以 setter 方式直接增加屬性。

子節點之增加,除了 addChild() 外,亦可以 setter 直接建立。故第18行直接以 setter 增加 <Table> 節點。但此方式僅限單一子節點。

第一個子節點可藉由 setter 直接建立,無須先以 addChild() 建立子節點。然而第二個以後之同名子節點便不能由 setter 直接建立,必須以 addChild() 添加。故第36及44行之第2及第3儲存格 <Cell> 皆須以 addChild() 方法加入。

使用 SimpleXML 存取節點之途徑很多。我們可透過類似 XPath 之語法描述之根節點到目標節點的路徑存取,也可以透過子節點之參照以速記方式存取子節點以下之目標節點。我將之並列於程式碼中供各位參考。

最後使用 asXML() 方法將 SimpleXML 個體轉成 XML 字串,並存入指定的檔案 test1.xml 中。該 XML 文件可以 MS Excel 2000/XP 與 OpenOffice 開啟,試算表中包含一行三列之內容。

本文是 php-SpreadsheetReader 專案之一部工作。

Posted by shirock at 樂多Roodo! │15:58 │回應(0)引用(1)PHP
樂多分類:網路/3C 共同主題:PHP基本語法 工具:加入樂多書籤編輯本文
Ads by Roodo! 

引用URL

http://cgi.blog.roodo.com/trackback/2981347
引用列表:
以 PHP SimpleXML 實踐 MS Excel 2k/XP XML 文件之匯出工作
以 SimpleXML 將 CSV 文件轉換成 MS Excel 2k/XP XML 文件【石頭閒語】 at 2007年04月17日 17:12