用 XSD 驗證 XML 方法
維運或串接外部系統時,XML 最麻煩的地方通常不是「看不懂內容」,而是「規則到底是什麼」。有些欄位是必填、有些順序不能亂、有些節點要帶 namespace,肉眼看 XML 很容易漏掉,等送到對方系統才被打回來。
這時候 XSD 就很好用,因為它不是單純的範例文件,而是 XML 的結構規格。只要把 XML 拿去對照 XSD 驗證,就能先知道格式到底合不合規則。
先講清楚:XML 跟 XSD 分別是什麼
- XML:實際交換的資料內容。
- XSD:描述 XML 結構、欄位型別、節點順序、是否必填的規格文件。
例如下面這種 XML:
|
|
如果搭配 XSD,系統就可以檢查:
order節點是不是根節點。orderNo、amount是否都有出現。amount是否為數字。- 節點順序有沒有錯。
這比單靠人工檢查可靠很多。
我通常怎麼做驗證
我會分成 3 種情境:
- 先用編輯器快速檢查。
- 本機開發時用工具即時提示。
- 上線前或批次處理時用指令做正式驗證。
下面分別整理。
方法 1:用 Notepad++ 快速驗證
如果只是臨時拿一份 XML 來看,Notepad++ 真的很方便,啟動快、驗證也直觀。
優點:
- 不用另外寫程式。
- 很適合臨時開檔檢查。
- 維運或支援人員也比較容易上手。
如果手上是單次問題單、客戶回報檔案異常,這種方式通常夠快。
參考:
方法 2:用 VS Code 做日常編輯與驗證
如果你平常就用 VS Code,推薦安裝 Red Hat 的 XML 套件:
這個套件的優點是:
- 編輯時就能提示結構錯誤。
- 能配合 XSD 做自動補全。
- 對 namespace 與 schema 關聯處理得不錯。
要注意的是,它通常需要 Java 環境,若安裝後沒有反應,先確認本機 Java 是否正常。
方法 3:用 xmllint 指令做正式驗證
如果要把 XML 驗證納入 shell script、 CI 或批次檢查流程,我最推薦 xmllint。
基本語法:
|
|
參數說明:
--schema:指定 XSD 檔案。--noout:不要把 XML 全部印出來,只顯示驗證結果。
驗證成功時,通常會看到類似:
|
|
失敗時,會直接指出哪個節點、哪一行、哪種規則不符合。
如果 XML 本身有綁 schema
有些 XML 會自己帶上 schema 位置,例如:
|
|
這樣編輯器通常比較容易自動找到對應規則。不過很多實務場景拿到的是純 XML,schema 另外給,所以還是要會用手動指定 XSD 的方式。
常見踩雷點
1. namespace 不一致
很多 XML 看起來內容對,但其實 namespace 不對,驗證一樣會失敗。常見症狀是:
- 節點名稱一模一樣。
- 但 validator 還是說找不到對應 element。
這通常不是資料錯,而是 namespace 對不上。
2. 節點順序錯誤
XSD 常會規定 element 順序,像 header 一定要在 body 前面。人眼看 XML 會覺得「都有就好」,但 validator 不會這樣想。
3. import / include 找不到檔案
有些 XSD 不是單一檔案,而是主 schema 再 include 或 import 其他 schema。這時候只拿到主檔不夠,附屬 XSD 也要在正確路徑。
4. 編碼問題
像是 UTF-8、Big5、UTF-16 混用,或 XML 宣告與實際檔案編碼不一致,也會造成驗證過程出現奇怪問題。
我自己的驗證流程
實務上我通常這樣做:
- 先用 VS Code 或 Notepad++ 打開,快速看有沒有明顯格式錯。
- 確認 schema 檔案是否完整,特別是 include/import 的依賴。
- 用
xmllint跑一次正式驗證。 - 如果是要送給外部系統,再對照對方規格文件確認版本號與 namespace。
這樣做的好處是,編輯器負責提高閱讀效率,xmllint 負責做可重複、可自動化的最終確認。
電子發票 / MIG XSD 相關參考
如果你剛好是在找台灣電子發票或 Turnkey 相關的 XSD,下面這幾個資料我之前有用來交叉確認:
- 瑞曲之聲: C# 簡易電子發票資料 Turnkey 交換範例
- 不好意思,因為沒聯絡方式,所以只好在這邊留言詢問 · Issue #1 · RichieHsu/ENVITest
- ENVITest/CSharp/ENVITest/EInvoiceXSD/v31 at master · RichieHsu/ENVITest
- 電子發票 TurnKey 用 XML 相關參考 | 程式猿 Fighting! - 點部落
心智圖
小結
XML 最麻煩的不是標籤很多,而是規則通常藏在 XSD 裡。只要把 XSD 驗證納入日常流程,很多「送出去才被退件」的問題其實可以提早在本機抓掉。
如果只是偶爾看檔案,Notepad++ 很快;如果是平常開發,VS Code 會舒服很多;如果要放進 script 或 CI,還是 xmllint 最實在。