2010-10-27 38 views
7

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); 
       } 
      } 
     } 
    } 

Trả lời

2

Tôi nghĩ rằng tôi chỉ muốn sử dụng một StreamReader, xây dựng với bảng mã đúng và qua đó với phương pháp XmlReader.Create (TextStream):

using (var sr = new StreamReader(@"c:\temp\bad.xml", Encoding.BigEndianUnicode)) { 
    using (var xr = XmlReader.Create(sr, new XmlReaderSettings())) { 
     // etc... 
    } 
} 
1

Nếu không có hướng dẫn xử lý phù hợp khác, bạn có thể bỏ qua chúng bằng cách đặt XmlReaderSettings.IgnoreProcessingInstructions.

+1

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

Các vấn đề liên quan