簡介
在上一篇文章「Differential backup using 7-Zip for Windows (Part 1) - 利用 7-Zip 進行差異備份(上篇)」中,介紹了如何利用 Open Source 軟體 7-Zip 壓縮程式,來進行差異備份。並使用 Windows/DOS 的 cmd batch 批次檔案,自動為備份檔名附加日期時間戳記。本文將繼續說明在撰寫 cmd batch 批次指令時,遇到的各種問題(陷阱)與解決方法。
在上一篇文章「Differential backup using 7-Zip for Windows (Part 1) - 利用 7-Zip 進行差異備份(上篇)」中,介紹了如何利用 Open Source 軟體 7-Zip 壓縮程式,來進行差異備份。並使用 Windows/DOS 的 cmd batch 批次檔案,自動為備份檔名附加日期時間戳記。本文將繼續說明在撰寫 cmd batch 批次指令時,遇到的各種問題(陷阱)與解決方法。
在上一篇文章『HTML 資訊汲取(中篇) - Default namespace 問題』中提到:在 XPath 中,沒有所謂 default namespace (預設命名空間)。若 XPath 路徑未使用 prefix (前置字符) 指明 namespace,則其對應的 namespace 為 empty namespace (空命名空間)。因此,若在 XML 文件中定義了 default namespace,則所有的標籤必定都歸屬於某個不為空的 namespace。此時,未指明 namespace 的 XPath 路徑,將對應不到任何元素。
另一方面,TagSoup 處理過的 HTML 文件,有三個與 namespace 有關的問題:
xmlns="http://www.w3.org/1999/xhtml" 這個 default namespace,以及xmlns:html="http://www.w3.org/1999/xhtml" 這個以 html 為 prefix 的 namespace。而其餘的 namespace 的定義,都將被移除。 html 這個 prefix,才能對應到元素。 html,都會被修改並對應到 urn:x-prefix:html 這樣的 URI(參考 TagSoup 原始碼中 Parser 類別的 foreign() 函數、ElementType 類別的 namespace() 函數以及 change log),因而使該標籤對應不到原本正確的 namespace 的 URI。導致使用了該 prefix 的 XPath 路徑,也對應不到正確的標籤。(原本應該能正確對應的,這一點可以經由使用 JDOM 內建的 XML 解析器的實驗證明。) 內建的 XML 解析器不會有 namespace 的問題,但是無法處理 non-well-formed HTML。顯然此路不通…。
TagSoup 可以處理 non-well-formed HTML,但是會有 namseapce 問題。該是時候放棄 TagSoup,另找一個 HTML 解析器了嗎?還是如果我們可以配合 TagSoup 輸出的 namespace 定義,在 XPath 中一律使用 html prefix;或是,相反地,讓 TagSoup 不輸出 namespace 。是否就可以解決問題呢?(雖然邏輯上還存在著一個完美的可能性,就是讓 TagSoup 不輸出 default namespace,也同時能保留外部 namespace 的定義,不過這並不容易達到。這已牽涉到 TagSoup 的設計架構了,除非大幅修改 TagSoup 的架構,讓它正確處理外部 namespace 的定義。但是這已經超出本文的目的了。)
在上一篇文章『HTML 資訊汲取(上篇) - 使用 JDOM 、 TagSoup 及 XPath』裡,我提到了如何利用 JDOM 搭配 TagSoup,並使用 XPath 簡單地汲取資訊。其實,在上一篇的範例裡,我刻意避開了兩個困擾許多人的問題:namespace(命名空間)問題以及TagSoup 的輸出問題。
再看一下上一篇出現的新聞標題:
<span class="titletext">曾雅妮的魔幻數字與粉紅色</span>
假設,除了 span 之外,還有其他標籤,譬如 h4,也具有 titletext 類別,但是只有 span 是我們要的新聞標題。在這樣的情況下,為了僅選擇 sapn 標籤,我們應該將原來的 XPath:
//*[contains(@class,'titletext')]
改成這樣:
//span[contains(@class,'titletext')]
將此 XPath 套用到上一篇的程式中,執行看看。
def xpath = XPath.newInstance( "//span[contains(@class,'titletext')]" )
def result = xpath.selectNodes( doc )
result.each { println it.text }
看看輸出結果。看到了嗎?沒有任何輸出!
Grails 雖然在專案根目錄下的 application.properties 檔案中,儲存了專案的設定資料。但是諸如 plugin 等,於專案開發、編譯期間所需要的 resource、script 及 template 等,甚至 plugin 的說明文件,卻都不是儲存於專案目錄下,而是另外存放在 user home 底下。每個專案,依其專案名稱(於建立專案時,由 grails create-app 命令指定),皆有專屬目錄存放該專案的相關資源。
該目錄所在位置,在 user home 的 .grails\{grails 版本}\projects 下,譬如:
C:\Documents and Settings\Administrator\.grails\1.3.5\projects\{專案名稱}
關於這一事實,有以下兩個問題必須加以關注: