HTML 資訊汲取(下篇) - TagSoup 輸出 namespace 問題的解決方案

Namespace 問題

在上一篇文章『HTML 資訊汲取(中篇) - Default namespace 問題』中提到:在 XPath 中,沒有所謂 default namespace (預設命名空間)。若 XPath 路徑未使用 prefix (前置字符) 指明 namespace,則其對應的 namespace 為 empty namespace (空命名空間)。因此,若在 XML 文件中定義了 default namespace,則所有的標籤必定都歸屬於某個不為空的 namespace。此時,未指明 namespace 的 XPath 路徑,將對應不到任何元素。

另一方面,TagSoup 處理過的 HTML 文件,有三個與 namespace 有關的問題:

  1. TagSoup 處理過的 HTML 文件,一律輸出為 XHTML 格式,並且定義了 xmlns="http://www.w3.org/1999/xhtml" 這個 default namespace,以及xmlns:html="http://www.w3.org/1999/xhtml" 這個以 html 為 prefix 的 namespace。而其餘的 namespace 的定義,都將被移除。
  2. 由於 TagSoup 處理過的 HTML 文件,含有 default namespace 的定義,使用 XPath 選取元素時,一定要在路徑的標籤或屬性前,加上 html 這個 prefix,才能對應到元素。
  3. TagSoup 處理過的 HTML 文件,其元素標籤若含有 prefix 定義,即使 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 的定義。但是這已經超出本文的目的了。)

Read More

HTML 資訊汲取(上篇) - 使用 JDOM 、 TagSoup 及 XPath

簡介

本文將以實際範例介紹如何以 JDOM 搭配 TagSoup ,將 HTML 解析為 DOM 文件物件模型,並使用 XPath 汲取資訊,或者將文件輸出為 XHTML 格式。

資訊汲取

Internet 上蘊藏著豐富的內容,供人們分享訊息、傳承知識。但是在 Semantic Web 普及之前,除非資料來源網站主動提供資料存取 API,否則,要擷取既有 Internet 上的資訊,還是只能從解析 HTML 著手。

雜亂無章的 HTML (Malformed and faulty HTML)

但是眾所週知,即使存在著如 XHTML 標準規範,網路上還是充斥著各種不合乎標準的 HTML 網頁。這個現象,甚至還有個專用名詞,叫做 Tag soup

Read More

Grails 專案維護 - 專案設定資料夾

Grails 雖然在專案根目錄下的 application.properties 檔案中,儲存了專案的設定資料。但是諸如於專案開發、編譯期間所需要的 resource、script 及 template 等,甚至 plugin 及其說明文件,卻都不是儲存於專案目錄下,而是另外存放在 user home 底下。每個專案,依其專案名稱(於建立專案時,由 grails create-app 命令指定),皆有專屬目錄存放該專案的相關資源。

該目錄所在位置,在 user home 的 .grails\{grails 版本}\projects 下,譬如:

1
C:\Documents and Settings\Administrator\.grails\1.3.5\projects\{專案名稱}

關於這一事實,有以下兩個問題必須加以關注:

Read More