2012年4月16日 星期一

Flex 解析 XML

前陣子在 Flex 上實作簡單的所見即所得編輯器,當時是參考網路上的範例,利用既有的「TextArea」再加上「TextFlow」的操作達成,不過在儲存的時候遇到狀況。因為不是單純只在 Flex 裡呈現,所以需要讓它輸出成較接近 HTML 格式的內容。而 Flex 既有的 TextConverter 類別,只支援很古早的 HTML 語法,不但使用早就不建議使用的「<Font>」標籤,而且還會漏掉一些像是文字背景色的屬性。

為了記錄屬性以及避免未來可能發生的語法問題,只好去查文件去自行建立編/解碼的 TextFormat 類別,花了一天多的時間,將當下用到的屬性都加進去,能夠編/解(自認為)符合 HTML 5 格式的字串,一開始的使用上沒有遇到什麼問題,一直到同事反應出狀況才將這個放了一兩個月的程式再翻出來。

問題是在行首或是字型修改後的空白很容易失踪,在編輯介面可以很正常的輸入,但一到了預覽介面就消失了。

聽到問題的當下猜想,會不會是顯示文字的排版引擎自動將空白忽略,就像是 HTML 格式中再多的空白連在一起,也只會被當成一個,而行首的空白則是直接被忽略。事後證明這個假設是錯的,首先是 Flex 的 TextFlow 和瀏覽器不同,不是吃 HTML 格式的 XML,所以根本就不會有空白被自動忽略的問題。

雖然這個假設不是問題發生的原因,不過仍然對它進行修改,將可能出問題的字元進行編碼,像是「空白」改成「&nbsp;」,以免未來在其它解析 HTML 的瀏覽工器上出現問題。

在增加中斷點測試後發現,編碼出來的資料是有包含空白,數量和位置都沒有問題,因此問題就指向解碼的時候。最終發現問題,並將之反解以解決問題,其中發現幾個現象。

我所採用的 HTML 5 格式是 XML 的一種,因此可以將之視為 XML 來解析,在解析之中我們常常會用
XML.ignoreWhitespace = true;
來讓解析出來的內容不要帶有那麼多不必要的空白。只是在 Flex 中它也會將內容前後的空白忽略,像是底下的例子…
var str:String = "   aaa   bbb   ccc";
var xmlList:XMLList = new XMLList(str);
trace(xmlList[0].toXMLString());
// 結果是︰aaa   bbb   ccc 前面的空白不見了…

所以必須在解析 XML 之前設定 XML.ignoreWhitespace = false; ,讓空白會被忽略,才能保留希望留下來的資料。一定要在解析之前,已經解析過的 XML 資料,再設定無法找回已經篕失的空白,猜想應該是一開始就沒有被存入物件中。

另外,被轉換成「&nbsp;」(空白)的字元,在 Flex XML 解析的時候會被處理,不過在 flex 中並不是原來的空白(字元碼不同),所以雖然在 trace 的時候看起來很正常,但是實際上並無法順利顯示出來,猜想是沒有這個特殊字元的字型,所以需要將它再進行轉換成一般的空白字元才行。至於在其它瀏覽器中 &nbsp; 是不是也是一個特殊字元,就不是我所知道的。

1 則留言:

  1. 最近在寫flex~很多很有價值的參考~~

    你寫的東西都很棒~~很感謝~~要繼續分享唷!!

    感恩 ^O^


    回覆刪除