Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 反序列化UTF-16编码格式的xml文件时发生XmlException_C#_Xml_Encoding_Xmlserializer_Xmlexception - Fatal编程技术网

C# 反序列化UTF-16编码格式的xml文件时发生XmlException

C# 反序列化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

使用C#的XmlSerializer

在反序列化给定文件夹中所有xml文件的过程中,我看到了XmlException
“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);
        }
    }