2010-10-27 24 views
7

Bir soket üzerinden harici bir arabirimden alınan bazı XML dosyalarını okumaya çalışıyorum. Sorun, kodlamanın XML üstbilgisinde yanlış belirtilmesidir (iso-8859-1 diyor, ancak utf-16BE'dir). Kodlamanın utf-16BE olduğu, ancak doğru kodlamayı kurmayı unuttuğunu belgelendi. Ben böyle bir StringReader kullanmak serisini zaman XML'yi ayıklarken belirtilen kodlamayı yok sayma

kodlamasını görmezden: Yukarıdaki aslında gayet iyi çalışıyor

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

, ama ben sadece ReadLine arayarak başlık satırı atlamak kısmını sevmiyorum. XML üstbilgisinde belirtilen kodlamayı atlamak için daha az kırılgan bir yol var mı? Bir StreamReader kullanarak

StreamReader ile

Çözelti, XML-başlığında belirtilen kodlama geçersiz kılabilir. XmlReaderSettings.Ignore ProcessingInstructions belirtme veya herhangi bir değişiklik yapmadı. İlginç bir şekilde StreamReader, bir unicode bayt sırası işareti bulduğunda belirtilen kodlamayı yok sayar. Özetlemek gerekirse

:

  • XmlReader bir TextReader ile başlatıldı, XML başlık kodlama göz ardı edilir.
  • Bir StringReader kullanılıyorsa, bir unicode bayt sırası işareti varsa XmlReader başarısız olur.
  • Bir StreamReader kullanılıyorsa, bir Unicode bayt sırası işareti StreamReader kodlamasını geçersiz kılar.
  • XmlReaderSettings.IgnoreProcessingInstructions = true, bir TextReader kullanırken fark yaratmaz.

Sonuç olarak, en sağlam çözüm, varsa, bayt sırası işaretini kullandığından bir StreamReader kullanıyor görünmektedir. Hiçbir diğer ilgili işlem yönergeleri varsa

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

cevap

2

Ben sadece doğru kodlama ile yapılmış bir StreamReader, kullanımı ve XmlReader.Create (TextStream) yöntemine olduğunu geçerdi düşünüyorum:

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