.net – 反序列化XML时忽略指定的编码

前端之家收集整理的这篇文章主要介绍了.net – 反序列化XML时忽略指定的编码前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图通过套接字读取从外部接口收到的一些 XML.
问题是 XML头中的编码指定错误(它表示iso-8859-1,但它是utf-16BE).据记载,编码是utf-16BE,但显然他们忘记设置正确的编码.

要在反序列化时忽略编码,我使用如下的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字节顺序标记,则忽略指定的编码.

回顾一下:

>如果使用TextReader初始化XmlReader,则忽略XML标头编码.
>如果使用StringReader,如果存在unicode字节顺序标记,则XmlReader将失败.
>如果使用StreamReader,则unicode字节顺序标记将覆盖StreamReader编码.
> XmlReaderSettings.IgnoreProcessingInstructions = true在使用TextReader时没有区别.

总之,最强大的解决方案似乎是使用StreamReader,因为它使用字节顺序标记(如果存在).

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);
                }
            }
        }
    }
我想我只是使用一个StreamReader,使用正确的编码构造并将其传递给XmlReader.Create(TextStream)方法
using (var sr = new StreamReader(@"c:\temp\bad.xml",Encoding.BigEndianUnicode)) {
     using (var xr = XmlReader.Create(sr,new XmlReaderSettings())) {
         // etc...
     }
 }

猜你在找的XML相关文章