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 開啟,試算表中包含一行三列之內容。
相關文章
樂多舊網址: http://blog.roodo.com/rocksaying/archives/2981347.html