Tôi đang cố gắng đọc một số XML nhận được từ một giao diện bên ngoài qua một ổ cắm. Vấn đề là mã hóa được chỉ định sai trong tiêu đề XML (nó nói iso-8859-1, nhưng nó là utf-16BE). Đó là tài liệu rằng mã hóa là utf-16BE, nhưng dường như họ quên đặt mã hóa chính xác.Bỏ qua mã hóa được chỉ định khi deserializing XML
Để bỏ qua các mã hóa khi tôi deserialize tôi sử dụng một StringReader như thế này:
private static T DeserializeXmlData<T>(byte[] xmlData)
{
var xmlString = Encoding.BigEndianUnicode.GetString(xmlData);
using (var reader = new StringReader(xmlString))
{
reader.ReadLine(); // Eat header line
using (var xmlReader = XmlReader.Create(reader))
{
var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(xmlReader);
}
}
}
Trên đây thực sự hoạt động tốt, nhưng tôi không thích những phần mà tôi chỉ cần bỏ qua dòng tiêu đề bằng cách gọi ReadLine. Có cách nào dễ dàng hơn để bỏ qua mã hóa được chỉ định trong tiêu đề XML không?
Giải pháp với StreamReader
Bằng cách sử dụng một StreamReader, tôi có thể ghi đè mã hoá được quy định trong XML-header. Chỉ định XmlReaderSettings.IgnoreProcessingInstructions hoặc không làm bất kỳ sự khác biệt nào. Điều thú vị là StreamReader bỏ qua mã hóa được chỉ định nếu nó tìm thấy một dấu thứ tự byte unicode.
Để tóm tắt:
- Nếu XmlReader được khởi tạo với một TextReader, mã hóa XML-header được bỏ qua.
- Nếu một StringReader được sử dụng, XmlReader không thành công nếu một dấu thứ tự byte unicode tồn tại.
- Nếu một StreamReader được sử dụng, một dấu đơn hàng byte unicode sẽ ghi đè mã hóa StreamReader.
- XmlReaderSettings.IgnoreProcessingInstructions = true không tạo sự khác biệt khi sử dụng TextReader.
Kết luận, giải pháp mạnh mẽ nhất dường như đang sử dụng StreamReader, vì nó sử dụng dấu thứ tự byte, nếu có.
private static T DeserializeXmlData<T>(byte[] xmlData)
{
using (var xmlDataStream = new MemoryStream(xmlData))
{
using (var reader = new StreamReader(xmlDataStream, Encoding.BigEndianUnicode))
{
using (var xmlReader = XmlReader.Create(reader))
{
var serializer = new XmlSerializer(typeof (T));
return (T) serializer.Deserialize(xmlReader);
}
}
}
}
Tuyệt vời! Làm thế nào tôi sẽ xác định mã hóa "đúng" sau đó? (một XmlReader dựa trên một StringReader ném một ngoại lệ ngay cả với IgnoreProcessingInstructions thiết lập là true). – Holstebroe