XML parsing on different browsers

瀏覽器解析 XML 的不同行為

一個 XML 文件長這個樣子:一個文件類型宣告 (<?xml ?>)、一個根目錄 element 包含其他的 element。所以當 XMLHttpRequest 物件抓遠端的 XML 回來解析的時候,obj.responseXML 這個 XMLDocument Object 的 .childNodes.length 應該是 1 —— .firstChild 就是 root element 。

問題來啦:以上看似合理的 XML parsing 只發生在 Mozilla 上面。在 IE 裡面 childNodes.length 是 2,firstChild.nodeName 會傳回 … ?xml !這是怎樣?

那改用 .lastChild 去拿 root element 好了,這總不會出錯了吧。嘿嘿,不行 —— Operaobj.responseXML 更有趣:childNodes.length = 2 ,第一個 childNode 是 ?xml、第二個是 root、第三個是 … #text,nodeValue是長度 0 空字串。我檢查過,這絕對不是 Server 端的問題,因為那邊是用 PHP DOM 在生 well-formed XML 的。

最後我的解法還是用 obj.responseXML.lastChild 拿 root,不過在之前先經過一個判斷式:如果 .lastChild.nodeName == ‘#text’ 就做 removeChild 的動作。

這個解析 XML 的差異是因為各家瀏覽器 XMLHttpRequest 物件行為的不同,與 prototype.js 無關。prototype.js 只做 warpper 而已,裡面搞成這樣它應該是不知道。

還有另外一種解法是不要做 AJAX —— 做 AJAteXt,叫伺服器傳文字進來,再從 obj.responseText 抓出來處理。不是很正統而且還需要而額外寫解析函式的方法,但 GMail 好像就是這樣在抓信件內文的。

XMLHttpRequest on different browsers parses XML in different ways. An XMLDocument Object contains a <?xml ?> doctype declaration and a root element. Anything else should be child nodes under the root. Thus, when the XML file is fetched, obj.responseXML.childNodes.length should return 1, and firstChild should return the root element.

Sounds right? Not quite. What described above only occurs in Mozilla. In poor-designed IE6, childNodes.length returns 2 — firstChild.nodeName returns ?xml. Opera behaviors even weirder; childNodes.length returns 3, first two are same as IE, and the their one is a #text with zero-length string nodeValue.

I ended up using lastChild to retrive the root element after checking its nodeName; if lastChild.nodeName == ‘#test’ { removeChiid(); } .

The other solution is to abandon AJAX – use AJAteXt instead. By parse responseText on your own code, you could avoid these kind of inconsistent behaviors. Kind of non-standard method, but AFAIK, Gmail does use AJAteXt to retrieve mail text.

惡搞 KKMAN

KKMANPCMan並列為台灣兩大 Telnet BBS + WWW Client ,也是市場上僅有的具有 Telnet 功能的瀏覽器。KKfox (Firefox 的 KKMAN 模仿+增強) 因為 PCMan Plugin 不穩定所以一直不好用。所以我就反過來想:KKMAN 不是開放源碼軟體,法律上和實際上都無法自行修改;不過一些能做的方法還是可以試試看。

惡搞 1. Gecko KKMAN:用 Gecko 排版引擎的 KKMAN

KKMAN 內部的瀏覽器元件是 IE。原因無它,只是因為每台 Windows 都有,不需要叫使用者額外判斷他是不是該另外下載什麼程式;ActiveX 控制項也很容易匯入。Mozilla 專案有發展相對應的 Gecko 排版引擎 ActiveX 控制項;所以現在要做的就是安裝控制項、然後把 KKMAN 呼叫 IE 的部份全部改呼叫 Gecko。

  1. 下載最新版 Mozilla ActiveX control並安裝。似乎要重開機。
  2. 使用 IE patcher 修改 KKman.exe 。

實驗結果:G-KKMAN 啟動成功,但是程式極端不穩定;按個網頁的上一頁按鈕就當機。PCMan Combo 則是沒有辦法修改,因為 IE Patcher 沒有找到 IE 插入的位置。

惡搞 2. KKMAN over Wine

我知道 Linux 上面有 PCManX 可以用 (真的不錯),但是它沒有瀏覽器功能。所以還是要求助 Wine 了。要把環境準備好給 KKMAN 有點麻煩:

  1. 要先把 Wine 環境先裝上 IE。我用的是 ie4liunx,也沒有其他更方便的方法了。裝好之後把 ~/.ies4linux/ie6 移動到 ~/.wine ,還要修改 ~/bin/ie6 裡的路徑。
  2. 下載並且安裝 KKMAN 。安裝程式會順利在 Wine 下執行。
  3. 從 Windows 複製一個 KKMAN 需要但是自己沒附的DLL檔:C:\WINDOWS\system32\mfc42.dll 放在 ~/.wine/drive_c/Program_Files/KKman/
  4. 啟動 KKMAN:$wine ~/.wine/drive_c/Program_Files/KKman/KKMAN.exe

實驗結果:可以正常使用!但是不知道為什麼分頁切換按鈕不見了;倒是 Ctrl+num 和 Ctrl+Tab 還是可以用。PCMan Combo 則是完全無法在 Wine 上面執行;只要開啟網頁就當機,順便把 Gnome Panel 拖下水。PCMan Combo 也可以執行,但方向鍵失效、分頁按鈕也怪怪的。瀏覽到某特定網頁會當機。

KKMAN over Wine on Linux

結論

包 IE 的程式在 Windows 上面本來就不穩定啦,但是其他解決方案至少要比那些程式穩定才算可行。所以大家一起等 Firefox PCman Plugin 完成吧。

(倒是那時候還有人在用BBS嗎?)

So Ubuntu is the bad guy?

Ubuntu vs. Debian: What Canonical Doesn’t Want You To KnowDigg 上的文章。

其實我的草稿裡面一直有一篇 My Linux Choice is Ubuntu 沒有發表。Ubuntu 是個很棒的 Linux 散布版本,它的安裝程式很自動,畫面很漂亮,幾乎所有的設定都有圖形介面可以改 —— 就算是要用到命令列的設定,命令也幾乎是剪下貼上就可以了。還有可以一次更新所有程式的更新系統,這比 Windows 上面的 Windows Update 帥多了。

我一直沒有把那篇文章貼上來的原因是因為直接這樣說好像對其他 Linux 散布版本不是很公平 —— 或許其他 Linux (嗯,應該稱作 GNU/Linux) 能做同樣的事,做的比 Ubuntu 還要好也說不定。

倒是那篇文章現在說 Dibian Debian 的 Etch 分支不管安裝程式或是更新程式等都和 Ubuntu 一樣,甚至連 Ubuntu 使用手冊都可以套用在 Etch 身上。文章真正的意思是:Ubuntu 的成功不是這個作業系統的成功,而只是行銷一個品牌,一個自製版本的 Dibian Debian 的成功。

隨便啦XD。Ubuntu 還算是 My “current” Liunx choice。如果您不是 Linux 的用戶想要跳槽而且進行還算平穩的轉換的話,Ubuntu 真的是個不錯的選擇。「Ubuntu 是古非洲語,意思是『我不會設定 Dibian Debian』」還真的是這樣勒。

這個時代誰都可以當壞人呀。

Ubuntu vs. Debian: What Canonical Doesn’t Want You To Know, an article I found on Digg.

I’ve kept a draft saying My Linux Choice is Ubuntu for a long time. Ubuntu is a good Linux distro, it’s easy to install, it’s beautiful, you can do almost all configuration by GUI tools instead of command lines – even if you need to will still be as easy as copy and paste. Not to mention the wonderful update-all-apps-at-once updating service that even beats Windows.

But seriously I choose not to post that “My Choice” post is because it will be unfair to not to understand – at least try to – how other Linux (Oops! the right term is GNU/Linux) distro does; maybe they do everything Ubuntu does and do them as good as Ubuntu but I didn’t know.

But I choose not to publish the post anyway; it seems unfair to other Linux distro since they might able, or even good at, to do the same thing that Ubuntu does. (A reminder: GNU/Linux is the political correct term)

Now, that post claims “The installer in [Dibian Debian] Etch works the same way as it does in Ubuntu, Apt works the same way, even Ubuntu guides usually work fine in Debian.” and saying that “…is Ubuntu’s success really due to the OS itself or the successful marketing of a highly branded version of Debian? And more importantly, with this in mind, is Ubuntu getting far too much press for what it is?“.

Ubuntu is still my “current” Linux choice, and it should be yours too if you are new to Linux and considering smooth transition. Ubuntu is the African word for “I can’t config Dibian.” – it sure is.

In this era, everyone can be the bad guy.