C# 反序列化UTF-16编码格式的xml文件时发生XmlException
使用C#的XmlSerializer 在反序列化给定文件夹中所有xml文件的过程中,我看到了XmlExceptionC# 反序列化UTF-16编码格式的xml文件时发生XmlException,c#,xml,encoding,xmlserializer,xmlexception,C#,Xml,Encoding,Xmlserializer,Xmlexception,使用C#的XmlSerializer 在反序列化给定文件夹中所有xml文件的过程中,我看到了XmlException “XML文档(0,0)中有错误”。和InnerException是“没有Unicode字节顺序标记。无法切换到Unicode”。 目录中的所有XML都是“UTF-16”编码的。唯一的区别是,某些xml文件缺少在反序列化时使用其对象的类中定义的元素 例如,考虑到我的文件夹中有3种不同类型的XMLS: file1.xml <?xml version="1.0" encoding
“XML文档(0,0)中有错误”。
和InnerException是“没有Unicode字节顺序标记。无法切换到Unicode”。
目录中的所有XML都是“UTF-16”编码的。唯一的区别是,某些xml文件缺少在反序列化时使用其对象的类中定义的元素
例如,考虑到我的文件夹中有3种不同类型的XMLS:
file1.xml<?xml version="1.0" encoding="utf-16"?>
<ns0:PaymentStatus xmlns:ns0="http://my.PaymentStatus">
</ns0:PaymentStatus>
以下代码段为我执行反序列化操作:
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时,这似乎很好。很可能
encoding=“UTF-16”
与编码无关,XML被存储,从而导致解析器无法将流读取为UTF-16文本
因为您有评论说,将“encoding”参数更改为“utf-8”可以让您读取文本,所以我假设文件实际上是UTF8。通过在所选编辑器(即Visual Studio)中以二进制文件而不是文本打开文件,可以轻松验证这一点
产生这种不匹配的最可能的原因是将XML保存为writer.Write(document.OuterXml)
(首先获取字符串表示,它将“utf-16”放在首位,而不是默认情况下使用utf-8编码将字符串写入流)
可能的解决方法-以与编写代码对称的方式读取XML-读取为字符串,然后从字符串加载XML
正确修复-确保XML存储正确。我今天在使用第三方web服务时遇到了同样的错误 我遵循Alexei的建议,使用StreamReader并设置编码。之后,可以在XmlTextReader构造函数中使用StreamReader。下面是使用原始问题中的代码实现的:
foreach(文件路径中的字符串f)
{
XmlSerializer xsw=新的XmlSerializer(typeof(PaymentStatus));
FileStream fs=newfilestream(f,FileMode.Open);
StreamReader stream=新的StreamReader(fs,Encoding.UTF8);
PaymentStatus配置=(PaymentStatus)xsw.Deserialize(新的XmlTextReader(流));
}
我不知道这是否是最好的方法,但如果我的输入流不包含BOM,我只使用XDocument来处理不同的编码。。。例如:
public static T DeserializeFromString<T>(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);
}
}
publicstatict反序列化fromstring(stringxml),其中T:class
{
尝试
{
var xDoc=XDocument.Parse(xml);
使用(var xmlReader=xDoc.Root.CreateReader())
{
返回新的XmlSerializer(typeof(T))。反序列化(xmlReader)为T;
}
}
捕获()
{
返回默认值(T);
}
}
当然,您可能想抛出任何异常,但是对于我从中复制的代码,我不需要知道它是否失败或为什么失败。。。所以我就吃了这个例外
[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));
}
public static T DeserializeFromString<T>(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);
}
}