XML宣告(declaration)必須在第一行的第一個字元

今天在處理某客戶的資訊室傳遞過來的XML文件中,我用.NET的System.Xml.XmlDocument將其讀入之時,系統彈出了一個非常奇怪的錯誤訊息:

錯誤訊息如下:

這不是預期的 XML 宣告。XML 宣告必須在文件的第一個節點,且不允許在其前方出現空白字元。

Unexpected XML declaration. The XML declaration must be the first node in the document, and no white space characters are allowed to appear before it.

見鬼了,把這個XML文件貼到XML Parser之類的網站,例如:Code Beautify XML VIEWER,非常的奇怪,一切都良好啊?我的XML長得像下列這個範例,請各位看官評評理,到底是哪裡錯了:


<?xml version="1.0" encoding="UTF-8"?>
<note>
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

XML Declaration必須在第一行第一個字元

經過很多時間的折磨,我終於發現了原來上面的XML範例中,第一行第一個字為ENTER,所以XmlDocument在LoadXml時把它擋掉了。這...哪種鬼規定啊?開始狂找W3C的規範,不過怎麼翻也翻不到相關的規定,頂多只是說明若有存在XML Declaration,那麼必須被寫在「第一個節點(Node)」。

最終我在這個網站翻到這些定義(XmlWriter.net),算是很明確指出XML Declaration必須在第一行第一個字元,但是,這個網站並不是標準組織啊!

XML Rules:

  1. If the XML declaration is included, it must be situated at the first position of the first line in the XML document.
  2. If the XML declaration is included, it must contain the version number attribute.
  3. If all of the attributes are declared in an XML declaration, they must be placed in the order shown above.
  4. If any elements, attributes, or entities are used in the XML document that are referenced or defined in an external DTD, standalone="no" must be included.
  5. The XML declaration must be in lower case (except for the encoding declarations).

總結

(先說我是猜的)微軟在實作XmlDocument時,把XML declaration這個元素視為類似Windows在處理Unicode BOM(Byte Order Mark)時的規定,也就是字元語系啊什麼之類的必須在一開始就定義,好讓XmlDocument的類別程式碼去自動、自行切換編碼等屬性,微軟可能希望這個最終形成「約定成俗」的好習慣吧?但這最終也成為Linux陣營最討厭的規矩。

我個人是還蠻喜歡BOM的0xFF、0xFE規範的,所以對於這個XML的第一行第一個字元,除了有一點驚訝與無奈之外,其實也不是壞事,總之程式這回事,就是大家遵守規矩就好辦事嘍。(話說回來,這個XML也不是我產生的吧?唉,只好乖乖的多寫一個IndexOf()了...)

知道真正狀況的網友麻煩分享一下真正的定義來源吧!

XmlDocument.LoadXml XmlDeclarations UnexpectedXmlDeclaration UnicodeBOM