我有供应商提供的XML,因此我无法修改此XML文件的生成方式。我想将此文件反序列化为对象,但有时会发生我想要获取的重要信息是元素本身的名称。例如:
<type>
<BOOL />
</type>
当类型不是原始类型时,我没有遇到这个问题,因为我会得到这样的结果:
<type>
<derived name="CustomDatatype" />
</type>
该元素将始终命名为&#34;衍生&#34;并有一个属性&#34; name&#34;所以我只检查派生元素是否存在并获取name的值。
回到问题,在&#34;类型&#34; element我有另一个名为&#34; BOOL&#34;但它可能是19个原始数据类型的固定列表中的任何值类型,所以我最终这样做:
public class XmlType
{
//Here I show just two datatypes but remember that the list is larger
[XmlElement("BOOL",IsNullable = true)]
public string boolType{ get; set;}
[XmlElement("BYTE",IsNullable = true)]
public string byteType{ get; set;}
.
.
.
[XmlElement("derived",IsNullable = true)]
public DerivedTypeXml derivedType{ get; set;}
[XmlIgnore]
public string Type
{
get
{
if (this.boolType != null)
{
return "BOOL";
} else if (this.byteType != null) {
return "BYTE";
}else if(this.derivedType!=null)
{
return this.derivedType.Name;
}else
{
return "unknown";
}
}
}
}
}
正如你所看到的,我必须声明允许它们为null的可能元素,然后逐个检查它们是否存在并告诉它们必须返回什么。这感觉太多的工作和hacky所以我想知道是否有一个通用的解决方案。
编辑:好的,亚历山大的答案是对的,但为了满足我的需要,我不得不稍微调整一下。 [XmlIgnore]
public string primitiveType=string.Empty;
public string Type
{
get
{
if(primitiveType!=string.Empty)
{
return this.primitiveType;
}
else if(this.derivedType!=null)
{
return this.derivedType.Name;
}else{
return "#UNKNOWN";
}
}
}
private void XmlSerializer_UnknownElement(object sender, XmlElementEventArgs e)
{
var obj = (TypeXml)e.ObjectBeingDeserialized;
obj.primitiveType = e.Element.Name;
}
答案 0 :(得分:0)
尝试这样的事情:
public class XmlType
{
[XmlElement("derived", IsNullable = true)]
public DerivedTypeXml derivedType { get; set; }
// No need [XmlIgnore]
public string Type { get; set; }
}
在UnknownElement
的实例上创建XmlSerializer
事件处理程序。
xmlSerializer.UnknownElement += XmlSerializer_UnknownElement;
private void XmlSerializer_UnknownElement(object sender, XmlElementEventArgs e)
{
var obj = (XmlType)e.ObjectBeingDeserialized;
obj.Type = e.Element.Name;
}
这就是全部!
当序列化器遇到未知标签时,如BOOL,BYTE等将被称为事件处理程序。因此为Type
属性分配了此标记的名称。
请务必删除XmlIgnore
属性,以便为此属性调用事件处理程序。