忽略指定的编码方式在反序列化XML时。

8
我正在尝试通过套接字接收一些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字节顺序标记,它会忽略指定的编码。
总结一下:
  • 如果XmlReader使用TextReader初始化,则忽略XML头中的编码。
  • 如果使用StringReader,则如果存在Unicode字节顺序标记,XmlReader将失败。
  • 如果使用StreamReader,则Unicode字节顺序标记将覆盖StreamReader编码。
  • 当使用TextReader时,XmlReaderSettings.IgnoreProcessingInstructions = true没有任何效果。
因此,最可靠的解决方案似乎是使用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);
                }
            }
        }
    }
2个回答

4
我认为我会使用一个StreamReader,使用正确的编码构建,并将其传递给XmlReader.Create(TextStream)方法:
 using (var sr = new StreamReader(@"c:\temp\bad.xml", Encoding.BigEndianUnicode)) {
     using (var xr = XmlReader.Create(sr, new XmlReaderSettings())) {
         // etc...
     }
 }

1

1
太好了!那我该如何指定“真正”的编码呢?(基于StringReader的XmlReader即使设置为IgnoreProcessingInstructions也会抛出异常)。 - Holstebroe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接