如何追踪反序列化 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; }
}
其中 finalizacaoOrcamentoVO
是 inherits 来自 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);
}
}
这是我的 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; }
}
其中 finalizacaoOrcamentoVO
是 inherits 来自 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);
}
}