首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

XML 解析錯誤「前言中不允許有內容」根因分析與解決:BOM Header 陷阱

     編輯:Java 綜合教學

錯誤現場

org.dom4j.DocumentException: Error on line 1 of document: 前言中不允許有內容。
Nested exception: 前言中不允許有內容。
 at org.dom4j.io.SAXReader.read(SAXReader.java:482)
 at com.core.util.XmlTemplateUtil.loadXmlTemplateByIO(XmlTemplateUtil.java:93)
 ...

乍看之下,XML 檔案開頭並無多餘字元,為何解析器仍報「前言中不允許有內容」?

真兇:UTF-8 BOM (Byte Order Mark)

什麼是 BOM?

BOM 是位於檔案最開頭的 2~4 個位元組,用於標示編碼與位元組序:

  • UTF-16 BE:FE FF
  • UTF-16 LE:FF FE
  • UTF-8:EF BB BF(三個位元組)

XML 規範要求文件必須以 <?xml ...?> 宣告開頭,不允許任何前導位元組。許多編輯器(如 Windows 記事本)另存為 UTF-8 時預設會加入 BOM,導致解析器在讀取第一個字元時遇到 0xEF 而非 <,拋出上述異常。

驗證方法

  1. 用 UltraEdit / Notepad++ / VS Code 開啟檔案,切換至十六進制模式,檢查開頭是否為 EF BB BF。
  2. Linux/Mac 終端機:head -c 3 your.xml | xxd,輸出若為 ef bb bf 即確認有 BOM。

解決方案

編輯器操作步驟
Notepad++ 選單 編碼(E) → 轉為 UTF-8 (無 BOM) → 存檔
UltraEdit 檔案(F) → 轉換(C) → UTF-8 無 BOM
VS Code 右下角編碼欄位點擊 → 以編碼儲存(Save with Encoding) → 選 UTF-8 (without BOM)
IntelliJ IDEA File → File Encoding → UTF-8(預設不寫 BOM)
Linux 指令 sed -i '1s/^\xEF\xBB\xBF//' your.xml 移除首行 BOM

常見誤區

「改成 ANSI 編碼就好了」

ANSI(實際上是系統預設代碼頁,如 GBK/Big5)確實沒有 BOM,但無法支援多國語言字元。正確做法是保留 UTF-8 編碼,移除 BOM,兼顧相容性與國際化。

程式碼層面防禦(可選)

若無法控制上游檔案來源,可在讀取前預處理:

public static InputStream removeBom(InputStream in) throws IOException {
    PushbackInputStream pb = new PushbackInputStream(in, 3);
    byte[] bom = new byte[3];
    pb.read(bom);
    if (!(bom[0] == (byte)0xEF && bom[1] == (byte)0xBB && bom[2] == (byte)0xBF)) {
        pb.unread(bom); // 非 BOM,退回
    }
    return pb;
}

總結

「前言中不允許有內容」九成以上是 UTF-8 BOM 惹的禍。養成「儲存為 UTF-8 無 BOM」的習慣,或在 CI 流程加入 BOM 檢查,即可徹底杜絕此類問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved