我正在尝试通过套接字接收一些XML,并阅读它。问题在于XML头中指定的编码错误(它说是iso-8859-1,但实际上是utf-16BE)。已经记录了编码是utf-16BE,但显然他们忘记设置正确的编码。
为了在反序列化时忽略编码,我使用StringReader,如下所示:
上述方法实际上很好用,但我不喜欢只是通过调用ReadLine跳过头行的部分。有没有一种更不易出错的方法来绕过XML头中指定的编码呢? 使用StreamReader的解决方案 通过使用StreamReader,我可以覆盖XML头中指定的编码。指定XmlReaderSettings.IgnoreProcessingInstructions或不指定都没有任何区别。 有趣的是,如果StreamReader发现Unicode字节顺序标记,它会忽略指定的编码。
总结一下:
为了在反序列化时忽略编码,我使用StringReader,如下所示:
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);
}
}
}
上述方法实际上很好用,但我不喜欢只是通过调用ReadLine跳过头行的部分。有没有一种更不易出错的方法来绕过XML头中指定的编码呢? 使用StreamReader的解决方案 通过使用StreamReader,我可以覆盖XML头中指定的编码。指定XmlReaderSettings.IgnoreProcessingInstructions或不指定都没有任何区别。 有趣的是,如果StreamReader发现Unicode字节顺序标记,它会忽略指定的编码。
总结一下:
- 如果XmlReader使用TextReader初始化,则忽略XML头中的编码。
- 如果使用StringReader,则如果存在Unicode字节顺序标记,XmlReader将失败。
- 如果使用StreamReader,则Unicode字节顺序标记将覆盖StreamReader编码。
- 当使用TextReader时,XmlReaderSettings.IgnoreProcessingInstructions = true没有任何效果。
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);
}
}
}
}