如何追踪反序列化 XML 到 XSD 中的对象错误?

How To Track Down Deserialize XML to Object Error in XSD?

这是我的 xml 文件的示例:

<IFX xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="finalizacaoOrcamentoVO">
<dadosOrcamento>...</dadosOrcamento>
<faturamento>...</faturamento>
</IFX>

这是我自动生成的 Visual Studio 对象 class:

  /// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class IFX
{

    private IFXDadosOrcamento dadosOrcamentoField;

    private IFXFaturamento faturamentoField;

但是我每次尝试反序列化时都会遇到这个错误:

消息"Error document XML (1, 57)."字符串

这是我的反序列化方法:

                IFX document;
                XmlSerializer serializer = new XmlSerializer(typeof(object));
                using (var reader = XmlReader.Create(file.InputStream))
                {
                    document = (IFX)serializer.Deserialize(reader);
                }

关于应该修复什么的任何提示? 提前致谢!

这些是我的子class: ClassObject

xsi:type 属性是 {http://www.w3.org/2001/XMLSchema-instance}type 的缩写,是预期类型的​​ w3c standard attribute that is used to explicitly assert the type of its element. As explained in Xsi:type Attribute Binding Support, XmlSerializer interprets this to mean that the element is serialized from a polymorphic derived type

即如果您的 XML 看起来像:

<IFX xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="finalizacaoOrcamentoVO">
  <dadosOrcamento>
    <IFXDadosOrcamentoValue>A IFXDadosOrcamentoValue</IFXDadosOrcamentoValue>
  </dadosOrcamento>
</IFX>

然后 XmlSerializer 期望以下 类 将存在:

[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
[XmlInclude(typeof(finalizacaoOrcamentoVO))]
public partial class IFX
{
    private IFXDadosOrcamento dadosOrcamentoField;

    public IFXDadosOrcamento dadosOrcamento { get { return dadosOrcamentoField; } set { dadosOrcamentoField = value; } }
}

public class finalizacaoOrcamentoVO : IFX
{
    // This derived type may have some or all of the properties shown as elements in the XML file.
}

public class IFXDadosOrcamento
{
    public string IFXDadosOrcamentoValue { get; set; }
}

其中 finalizacaoOrcamentoVOinherits 来自 IFX 的类型。

注意 [XmlInclude(typeof(finalizacaoOrcamentoVO))] 的存在。此属性通知序列化器可能遇到的子类型,并且必须存在于每个允许的子类型。

完成后,XML 现在可以通过以下方式反序列化:

IFX document;
XmlSerializer serializer = new XmlSerializer(typeof(IFX));
using (var reader = XmlReader.Create(inputStream))
{
    document = (IFX)serializer.Deserialize(reader);
}

finalizacaoOrcamentoVO 的一个实例将由此实际创建。

也就是说,在您的评论中您声明您的自动生成 类 不包含派生类型 finalizacaoOrcamentoVO。如果您从 XSD 生成 类,则 XSD 和 XML 不匹配,您应该解决这个问题。如果您通过将 XML 粘贴到 Visual Studio 中生成 类,那么 Visual Studio 的代码生成中可能存在错误或限制,可以手动修复如上所示。

如果你真的想忽略 xsi:type 属性,那么你将不得不手动这样做,因为序列化程序内置了对它的支持。一种方法是加载到中间 XDocument:

XDocument xDoc;
using (var reader = XmlReader.Create(inputStream))
{
    xDoc = XDocument.Load(reader);
}

var attr = xDoc.Root.Attribute("{http://www.w3.org/2001/XMLSchema-instance}type");
if (attr != null)
    attr.Remove();

var document = xDoc.Deserialize<IFX>();

使用扩展方法:

public static class XObjectExtensions
{
    public static T Deserialize<T>(this XContainer element, XmlSerializer serializer = null)
    {
        if (element == null)
            throw new ArgumentNullException();
        using (var reader = element.CreateReader())
            return (T)(serializer ?? new XmlSerializer(typeof(T))).Deserialize(reader);
    }
}