我正在编写一个C#库,作为其功能之一,它需要能够从Web服务接受以下形式的XML并对其进行反序列化。
表格1:
<results>
<sample>
<status>status message</status>
<name>sample name</name>
<igsn>unique identifier for this sample</igsn>
</sample>
</results>
表格2:
<results>
<sample name="sample name">
<valid code="InvalidSample">no</valid>
<status>Not Saved</status>
<error>error message</error>
</sample>
</results>
这是我正在反序列化的课程:
namespace MyNamespace
{
[XmlRoot(ElementName = "results")]
public class SampleSubmissionResponse
{
[XmlElement("sample")]
public List<SampleSubmissionSampleResultRecord> SampleList { get; set; }
...
}
public class SampleSubmissionSampleResultRecord
{
...
/* RELEVANT PROPERTY RIGHT HERE */
[XmlAttribute(Attribute = "name")]
[XmlElement(ElementName = "name")]
public string Name { get; set; }
...
}
public class SampleSubmissionValidRecord
{
...
}
}
问题在于,在一个XML示例中,Sample元素的name属性是一个元素,而另一个是属性。如果我用XmlAttribute和XmlElement装饰我的类的属性,我在创建XmlSerializer的实例时会抛出异常。
我现在一直在谷歌搜索,我找不到任何处理这种情况的文档。我假设,但不确定,这是因为在创建XML模式时,您不应该为同一元素的属性和子元素使用相同的名称。
那么,我该怎么办?
一种解决方案可能是为不同类型提供两个完全独立的模型。这可能会奏效,但似乎并不优雅。
另一种选择可能是实现IXmlSerializable并编写一些精心设计的代码来在deserialize方法中处理它。对于一个简单的问题,这将是一个非常冗长的解决方案。
我希望的第三个选项:某种方式将XmlAttribute和XmlElement应用于同一属性,或等效的“或 - 或”属性。
第四个选项:更改XML来自的Web服务以始终使用一个表单。不幸的是,拥有它的人可能不愿意这样做。
答案 0 :(得分:0)
仅为Name
属性指定一个属性。这将正确解析出第一个xml表单。
public class SampleSubmissionSampleResultRecord
{
[XmlElement(ElementName = "name")]
public string Name { get; set; }
}
要解析第二个xml表单,请将XmlSerializer
订阅到UnknownAttribute
个事件。
var xs = new XmlSerializer(typeof(SampleSubmissionResponse));
xs.UnknownAttribute += Xs_UnknownAttribute;
在事件处理程序中,我们得到所需的值。
private void Xs_UnknownAttribute(object sender, XmlAttributeEventArgs e)
{
var record = (SampleSubmissionSampleResultRecord)e.ObjectBeingDeserialized;
record.Name = e.Attr.Value;
}