最近工作上遇到一個需求,大概是產生XML資料,再利用這個資料丟到別的系統,來做資料匯入,但按照spec做出來,對方卻一直說parse有問題,花了好久的時間核對才發現是BOM的問題Q__Q
BOM
位元組順序記號(英語:byte-order mark,BOM)是位於碼點U+FEFF的統一碼字元的名稱。當以UTF-16或UTF-32來將UCS/統一碼字元所組成的字串編碼時,這個字元被用來標示其位元組序。它常被用來當做標示檔案是以UTF-8、UTF-16或UTF-32編碼的記號。資料擷取自維基百科
http://zh.wikipedia.org/wiki/%E4%BD%8D%E5%85%83%E7%B5%84%E9%A0%86%E5%BA%8F%E8%A8%98%E8%99%9F
產生XML的程式如下
XmlDocument doc = new XmlDocument();
XmlDeclaration xmldecl;
//指定為UTF-8
xmldecl = doc.CreateXmlDeclaration("1.0", null, null);
xmldecl.Encoding = "UTF-8";
XmlElement root = doc.DocumentElement;
doc.InsertBefore(xmldecl, root);
//產生XML結構
XmlElement Dept = doc.CreateElement("Dept");
doc.AppendChild(Dept);
XmlElement RD = doc.CreateElement("RD");
Dept.AppendChild(RD);
doc.Save(@"D:\temp.xml");
因輸出的檔案看起來沒什麼問題,格式也都正確,但用二進位編輯器(如何使用二進位編輯器請看此篇)查看後,卻多出了一行亂碼
延伸閱讀:[IDE]NotePad++新增二進位編輯器模組(Hex Editor)
http://kyleshen616.blogspot.tw/2013/07/idenotepadhex-editor.html
因Save預設會是UTF-8編碼,故我們宣告了兩次BOM的UTF-8,解決方式有以下幾種
將XML使用WriteAllText逐行寫入
File.WriteAllText(@"D:\temp.xml", doc.OuterXml);
或者將XML Save不指定為UTF-8
using (var writer = new XmlTextWriter(@"D:\temp.xml", new UTF8Encoding(false)))
{
doc.Save(writer);
}