我有以下相当简单的XML,我正在尝试反序列化:
<props xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://foo.com/bar">
<prop name="foo1" xsi:type="xsd:string">bar1</prop>
<prop name="foo2" xsi:type="xsd:int">2</prop>
</props>
当我在这个XML上运行XSD.exe以生成一个模式然后再次运行它来生成C#类时,我最终会得到以下高度装饰的版本:
public partial class props
{
[XmlElement("prop", IsNullable = true)]
propsProp[] Items { get; set; }
}
public partial class propsProp
{
[XmlAttribute]
public string name { get; set; }
[XmlText]
public string Value { get; set; }
}
现在,当我尝试使用XmlSerializer将XML反序列化为这些类时,我得到以下异常:
System.InvalidOperationException:XML文档中存在错误(4,4)。 ---&gt;
System.InvalidOperationException:无法识别指定的类型:name ='string',namespace ='http://www.w3.org/2001/XMLSchema',at&lt; prop xmlns = “http://foo.com/bar'> ;.
xsi:type
属性可能是为了促进prop
值的某些多态性,但我并不关心 - 我只想要C#属性中的值。
我在这里做错了什么?如何将XML转换为C#类?
答案 0 :(得分:0)
我经历了完全相同的问题,对于引用预定义类型,它的解决方案非常简单,但对于原始类型,它的解决方案有些棘手。
首先,使用“ xsi:type
”有什么好处。我发现这个link非常有用,可以帮助我解决问题。
因此,我们在XML中使用xsi:type
来引用驱动类型,例如:
<X xsi:type="X1">
意味着X和X1是彼此驱动的类型,所以我通过使用继承来修复反序列化,方法是为子类型创建一个新类并使其从父类继承,我们还需要创建一个列表:
[XmlRoot(ElementName = "X1")]
public class X1: X
{
}
[XmlRoot(ElementName = "X1List")]
public class X1List
{
[XmlElement(ElementName = "X1")]
public X1 X1{ get; set; }
}
在已经使用X的另一个类中,还添加X1,如下所示:
[XmlRoot(ElementName = "Container")]
public class Container
{
...
[XmlElement(ElementName = "XList")]
public POCList XList{ get; set; }
[XmlElement(ElementName = "X1List")]
public X1List X1List{ get; set; }
...
[XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Xsi { get; set; }
}
这应该可以解决反序列化。
对于原始类型,这将是一个棘手的问题,但是您可以使用具有约束的泛型来实现相同的解决方案。