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

kee*_*eda 5 c# xml encoding xmlexception xmlserializer

使用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".

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

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

file1.xml

<?xml version="1.0" encoding="utf-16"?>
<ns0:PaymentStatus xmlns:ns0="http://my.PaymentStatus">
</ns0:PaymentStatus>
Run Code Online (Sandbox Code Playgroud)

file2.xml

<?xml version="1.0" encoding="utf-16"?>
<ns0:PaymentStatus xmlns:ns0="http://my.PaymentStatus">
<PaymentStatus2 RowNum="1" FeedID="38" />
</ns0:PaymentStatus>
Run Code Online (Sandbox Code Playgroud)

file3.xml

<?xml version="1.0" encoding="utf-16"?>
<ns0:PaymentStatus xmlns:ns0="http://my.PaymentStatus">
<PaymentStatus2 RowNum="1" FeedID="38" />
<PaymentStatus2 RowNum="2" FeedID="39" Amt="26.0000" />
</ns0:PaymentStatus>
Run Code Online (Sandbox Code Playgroud)

我有一个代表上述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; }
}
Run Code Online (Sandbox Code Playgroud)

以下片段为我反序列化:

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));
}
Run Code Online (Sandbox Code Playgroud)

我想念什么吗?它必须是某种编码格式,因为当我尝试用UTF-8手动替换UTF-16时,这似乎工作得很好。

Joh*_*ter 5

我今天在使用第三方Web服务时遇到了同样的错误。

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

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));
}
Run Code Online (Sandbox Code Playgroud)


Ale*_*kov 2

很可能encoding="utf-16"与存储的 XML 编码无关,从而导致解析器无法将流读取为 UTF-16 文本。

由于您评论说将“encoding”参数更改为“utf-8”可以让您阅读文本,因此我假设文件实际上是UTF8。您可以通过在您选择的编辑器(即 Visual Studio)中以二进制而不是文本形式打开文件来轻松验证这一点。

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

可能的解决方法 - 以与编写代码对称的方式读取 XML - 作为字符串读取,然后从字符串加载 XML。

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