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ışıyorprivate 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);
}
}
}
}
Great! O zaman "doğru" kodlamayı nasıl belirleyebilirim? (StringReader tabanlı bir XmlReader, IgnoreProcessingInstructions öğesi true olarak ayarlanmış olsa bile bir istisna atar). – Holstebroe