TIPS-Remove Invalid Characters From XML Document
遇到一個問題,用LogParser擷取系統事件寫成XML檔,要分析XML時,卻因為ASP.NET 2.0傳回了一個XML內容含有不合法字元的錯誤事件而導致XmlDocument.Load()發生錯誤。
ASP.NET 2.0的錯誤是:
Exception type: XmlException
Exception message: '', hexadecimal value 0x08, is an invalid character. Line 11, position 12.
很妙的是,上面那個單引號所夾的,就是一個0x08 ASCII字元,而這個錯誤訊息被原原本本放到LogParser所產生的XML文件<Message>...</Message>Node中。導致的分析程式用XmlDocument.Load要載入LogParser產出的XML時,讀到ASCII 08,發生一模一樣的錯誤。
這有點像學生跟老師告狀:
"老師,王大明剛才踢人家屁股!"
"他怎麼踢你?"
"老師你先轉過去... 就像這樣..." (啪!!)
我找到一份討論串,提到XML中被視為不合法的字元包含了0x01-0x19(不含0x0a, 0x0d),所以我寫了以下的try ... catch,在解析錯誤時,試著將不合法字元移除後重試,在我遇到的案例中,這一招管用。
這又是一個足以展現Regular Expression威力的好例子(有些人應該會用迴圈跑30次Replace解這個問題吧!),還不太會用RegEx的人請看這裡。
//分析結果
XmlDocument xd = new XmlDocument();
try
{ xd.Load(file);
}
catch (System.Xml.XmlException xe)
{ //將整個檔案讀成字串
string rawXml =
System.IO.File.ReadAllText(file);
string invalidCharsMatch =
"(?ims)[\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9\xb\xc\xe\xf" +
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19]";
//取代其中無效字元, 通通換成空字串
rawXml = System.Text.RegularExpressions.Regex.Replace(
rawXml,
invalidCharsMatch, "");
xd.LoadXml(rawXml);
}