若要在 Firefox 中測試 XPath,請將格式正確的 XML 測試資料貼到一個可對獨立於網頁的記憶體文件執行 XPath 1.0 的評估工具中,輸入運算式,然後檢查瀏覽器原生 DOM 所回傳的相符節點、序列化文字或純量值。匹配本身來自 Document.evaluate,這是 Firefox 在開發者主控台中同樣開放的介面,但評估是針對以 DOMParser 解析出來的 XML 文件,而不是當前的 HTML 分頁。這個區別很重要:HTML 和 XML 使用不同的規則解析,命名空間的處理也不同,在實際頁面上能通過的運算式,遇到真正的 XML 承載時仍然可能失敗。
Firefox 並不像 Chrome 那樣內建專屬的 XPath 面板,大多數開發者會改用瀏覽器主控台搭配輔助函式 $x(),再把相符的節點複製回腳本中。這在實際頁面上找元素時很方便,但目標是針對任意的 XML 片段(設定檔、SOAP 信封、RSS feed、SVG 資產,或儲存的伺服器回應)驗證 XPath 運算式時,這種方式就不太合用。這個任務的正確工具,是一個專門的 XPath 測試工具,它模擬 Firefox 內部的處理方式,但允許使用者自行提供文件。

為何 XPath 1.0 需要真正的 XML 文件
Firefox 實作了 W3C DOM Level 3 XPath 規格,該規格綁定 XPath 1.0。瀏覽器並不支援後續版本,因此序列(sequences)、對映(maps)、陣列、具型別的值,或正規表示式函式等特性都無法使用。在瀏覽器中能運作的任何東西,必然是 XPath 1.0;無法運作的,則超出此引擎的詞彙範圍。這也說明了為何使用 XSLT 2.0 或 XQuery 的伺服器端函式庫中能執行的 XPath,可能會與 Firefox 回報的結果悄悄不一致。
獨立文件之所以重要的第二個原因在於解析。HTML 解析對許多錯誤較為寬容,但 XML 並不會。標籤不對應、未跳脫的 & 符號,或缺少結尾元素,都會從 DOMParser.parseFromString 產生 parsererror 結果,XPath 步驟根本不會執行。把這個錯誤視為失敗,能在錯誤答案出現之前就中止測試,並讓開發者收到一個明確的訊號,知道是哪一份輸入有問題。MDN 關於 DOMParser.parseFromString 的參考資料描述了相同的行為。
準備帶有命名空間前綴的 XML 測試資料
XML 測試資料必須格式正確,且必須宣告運算式預計使用的每個前綴。常見的偽陰性來源,是在根元素上宣告預設命名空間(例如 xmlns="urn:books"),搭配未加前綴的 XPath 名稱。在 XPath 1.0 中,未加前綴的名稱只會選取沒有命名空間的元素,因此 //book 即使在文件明顯包含書目的情況下,仍會回傳零個相符結果。解決方法是在 XML 中將命名空間綁定到前綴,並在運算式中使用該前綴。
| XML 宣告 | 範例 XPath | 匹配結果 |
|---|---|---|
| xmlns="urn:books" on root | //book | 零個相符;未加前綴的名稱會略過預設命名空間。 |
| xmlns:b="urn:books" on root | //b:book | 符合所有 b:book 元素。 |
| xmlns:b="urn:books" on root | //*[local-name()='book'] | 會符合,但忽略實際的命名空間。 |
| 保留的 xml 前綴 | //*[@xml:lang] | 解析為 http://www.w3.org/XML/1998/namespace。 |
保留的 xml 前綴會對應到其標準命名空間,不需要額外宣告。其他任何前綴都必須出現在測試資料中,否則運算式會因為「未解析的前綴」錯誤而失敗。
在 Firefox 中執行 XPath 運算式
- 在 Firefox 分頁中開啟 XPath 測試工具。整個工具都在當前分頁內執行,不會上傳 XML 或運算式。
- 將格式正確的 XML 測試資料貼到來源窗格。請在根元素上為 XPath 將參考的每個前綴加入 xmlns:prefix="uri" 的明確宣告。測試資料長度必須低於 500,000 字元。
- 在運算式窗格中輸入 XPath 1.0 運算式。長度請保持在 2,000 字元以內,並盡量使用明確的絕對路徑或收斂過的上下文,避免在大型文件上進行廣泛的後代搜尋。
- 觸發評估。瀏覽器會以 application/xml 使用 DOMParser 解析 XML;如果結果為 parsererror,執行會中止並回報不一致之處。
- 讀取輸出。XPath 測試工具使用 Document.evaluate 搭配 ANY_TYPE,因此瀏覽器會回報運算式自然的結果類型:節點集、字串、數字或布林值。Document.evaluate 的參考頁面記載了相同的回傳類型契約。
- 把可正常運作的運算式複製到目標執行環境中,無論是伺服器端解析器、建構腳本或測試框架,並在那裡重新執行,因為伺服器函式庫可能實作了不同版本的 XPath 或不同的命名空間政策。
閱讀結果類型,而不僅僅是文字
輸出區域會以不同方式呈現每一種結果,讓開發者能辨識引擎實際回傳的內容。節點集結果會被收集起來,每個相符項目一行並加上編號;元素節點會被序列化為文字,屬性值會以明確的 @ 符號前綴顯示(例如 @id="42"),文位元組點會加上標記,註解節點同樣會加上標記。這些序列化輸出並不會以標記的形式插入實際頁面,這能避免相符的 XML 內含類似腳本文字時,引發常見的 XSS 類意外。
| XPath 回傳類型 | 範例運算式 | 測試工具顯示的內容 |
|---|---|---|
| node-set | //book/title | 每個相符項目一行,顯示序列化後的元素。 |
| string | string(//book[1]/@isbn) | 加上引號的單一字串值。 |
| number | count(//book) | 整數或小數計數。 |
| Boolean | boolean(//book[@price < 10]) | true 或 false。 |
| empty | //missing | 空結果,與解析錯誤或運算式錯誤不同。 |
空節點集與解析錯誤在呈現上刻意區分。零個相符的成功結果會被視為空結果並回報,而格式錯誤的運算式或 XML 解析失敗,則會產生穩定的 XPath 錯誤前綴,再加上瀏覽器本身的訊息。引擎的措辭可能因 Firefox 版本而異,而前綴則能讓診斷訊息在跨版本間保持一致。
貼上之前先了解限制
在獨立文件上作業有幾項硬性上限。XML 來源上限為 500,000 字元,運算式上限為 2,000 字元。節點集結果上限為 500 個相符節點,總顯示字元數上限為 1,000,000 個字元。達到相符上限會被視為失敗,而不是顯示截斷的前綴,因為部分答案可能看起來像完整答案,導致有瑕疵的定位器被部署到正式環境。請使用更具體的路徑或述詞來收斂運算式,然後再執行一次。
務實的工作流程從小型且具代表性的測試資料開始,再視需要逐步擴充。請為正向相符保留一份測試資料,並為已知的零相符情況保留另一份,因為空結果也是契約的一部分。當運算式負責守護某個分支時,請同時測試兩個方向。如果同一個查詢預期只找出一筆紀錄,那麼像 count(...) 這類計數運算式也應該回傳 1;如果回傳 0 或多個,則周圍的程式碼需要加入守護機制。
在目標執行環境中確認運算式
在 Firefox 中通過測試是必要條件,但並非充分條件。伺服器端函式庫通常會內建自己的 XPath 引擎,而在命名空間、空白字元處理及結果類型方面的規則可能有所不同。XPath 可以選取元素、屬性、文字、註解以及處理相關的節點,但相符並不代表 XML 符合商業規則:這個工作流程中沒有 XSD 或 DTD 驗證,而 DOMParser 預設不會對結構描述進行驗證。請把本地測試視為運算式語法和結構的證明,至於資料是否夠完整以供應用程式使用,則交由真正的執行環境來判斷。
若讀者傾向直接使用瀏覽器主控台,可以在這份在 Chrome 主控台中對任意 XML 檢查 XPath 的指南中找到相同工作流程的 Chrome 版本。Firefox 並沒有對應的一鍵面板,因此獨立文件工具仍是取得乾淨、可重現的 XPath 測試最可靠的路徑。
本地 XPath 作業的安全注意事項
XML 和運算式都不會離開這個分頁。這個工具不會擷取遠端文件、跟隨連結、執行腳本、插入相符的標記、修改來源,也不會儲存歷史紀錄。話雖如此,任何貼到開發者工具中的內容,都可能落入剪貼簿歷史、螢幕擷圖或螢幕分享畫面中,因此敏感的 XML 應比照其他除錯介面,套用相同的本機畫面與剪貼簿衛生原則。一旦運算式在本地完成驗證,移轉到目標環境時也應遵循最小暴露原則。