以UTF-16编码格式反序列化xml文件时出现XmlException

使用C#的XmlSerializer。

在反序列化给定文件夹中的所有xml文件的过程中,我看到XmlException "There is an error in XML document (0, 0)". 和InnerException是"There is no Unicode byte order mark. Cannot switch to Unicode".

目录中的所有xmls都是“UTF-16”编码的。 唯一不同的是,一些xml文件缺少在反序列化时我正在使用的对象类中定义的元素。

例如,考虑我的文件夹中有3种不同类型的xmls:

file1.xml

    

file2.xml

     

file3.xml

      

我有一个类代表上面的xml:

 [XmlTypeAttribute(AnonymousType = true, Namespace = "http://my.PaymentStatus")] [XmlRootAttribute("PaymentStatus", Namespace = "http://http://my.PaymentStatus", IsNullable = true)] public class PaymentStatus { private PaymentStatus2[] PaymentStatus2Field; [XmlElementAttribute("PaymentStatus2", Namespace = "")] public PaymentStatus2[] PaymentStatus2 { get; set; } public PaymentStatus() { PaymentStatus2Field = null; } } [XmlTypeAttribute(AnonymousType = true)] [XmlRootAttribute(Namespace = "", IsNullable = true)] public class PaymentStatus2 { private byte rowNumField; private byte feedIDField; private decimal AmtField; public PaymentStatus2() { rowNumField = 0; feedIDField = 0; AmtField = 0.0M; } [XmlAttributeAttribute()] public byte RowNum { get; set; } [XmlAttributeAttribute()] public byte FeedID { get; set; } [System.Xml.Serialization.XmlAttributeAttribute()] public decimal Amt { get; set; } } 

以下片段对我进行反序列化:

 foreach (string f in filePaths) { XmlSerializer xsw = new XmlSerializer(typeof(PaymentStatus)); FileStream fs = new FileStream(f, FileMode.Open); PaymentStatus config = (PaymentStatus)xsw.Deserialize(new XmlTextReader(fs)); } 

我错过了什么吗? 它必须是编码格式的东西,因为当我尝试用UTF-8手动替换UTF-16时,似乎工作得很好。

今天我遇到了与第三方Web服务一样的错误。

我通过使用StreamReader并设置编码来遵循Alexei的建议。 之后,StreamReader可以在XmlTextReader构造函数中使用。 这是使用原始问题中的代码实现的:

 foreach (string f in filePaths) { XmlSerializer xsw = new XmlSerializer(typeof(PaymentStatus)); FileStream fs = new FileStream(f, FileMode.Open); StreamReader stream = new StreamReader(fs, Encoding.UTF8); PaymentStatus config = (PaymentStatus)xsw.Deserialize(new XmlTextReader(stream)); } 

很可能encoding="utf-16"与编码XML无关,因此导致解析器无法以UTF-16文本的forms读取流。

由于你有评论说改为“encoding”参数为“utf-8”让你阅读文本我假设文件实际上是UTF8。 您可以通过在所选编辑器(即Visual Studio)中打开文件作为二进制而不是文本来轻松validation。

最有可能导致这种不匹配的原因是将XML保存为writer.Write(document.OuterXml) (首先获取字符串表示,其中放置“utf-16”,但是默认情况下使用utf-8编码将字符串写入流中)。

可能的解决方法 – 以对称的方式读取XML以编写代码 – 读取为字符串,而不是从字符串加载XML。

正确修复 – 确保正确存储XML。

我不知道这是否是最佳方式,但如果我的输入流不包含BOM,我只需使用XDocument来处理不同的编码…例如:

 public static T DeserializeFromString(String xml) where T : class { try { var xDoc = XDocument.Parse(xml); using (var xmlReader = xDoc.Root.CreateReader()) { return new XmlSerializer(typeof(T)).Deserialize(xmlReader) as T; } } catch () { return default(T); } } 

当然你可能想要抛弃任何exception,但是在我复制的代码的情况下,我不需要知道它是否或为什么失败…所以我只是吃了exception。