I'm writing a C# library that, as one of its functions, needs to be able to accept XML of the following forms from a web service and deserialize them.
Form 1:
<results>
<sample>
<status>status message</status>
<name>sample name</name>
<igsn>unique identifier for this sample</igsn>
</sample>
</results>
Form 2:
<results>
<sample name="sample name">
<valid code="InvalidSample">no</valid>
<status>Not Saved</status>
<error>error message</error>
</sample>
</results>
Here's my class that I'm deserializing to:
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
{
...
}
}
The problem is that in one XML sample, the name attribute of the Sample element is an element, and in the other it's an attribute. If I decorate the property of my class with both XmlAttribute and XmlElement, I get an exception thrown when creating an instance of XmlSerializer.
I've been googling for a good while now, and I can't find any docs that deal with this situation. I assume, but don't know for sure, that this is because when creating an XML schema, you're not supposed to use the same name for an attribute and a child element of the same element.
So, what do I do here?
One solution might be to have two totally separate models for the different types. That would probably work, but doesn't seem very elegant.
Another option might be to implement IXmlSerializable and write some elaborate code to handle this in the deserialize method. That would be an awfully verbose solution to a simple problem.
Third option I'm hoping for: some way of applying both XmlAttribute and XmlElement to the same property, or an equivalent "either-or" attribute.
Fourth option: Change the web service the XML comes from to use one form consistently. Unfortunately, the folks who own it may not be willing to do this.
Specify only one attribute to
Name
property. This will correctly parse out the first xml form.To parse the second xml form, subscribe the
XmlSerializer
to theUnknownAttribute
event.In the event handler, we get the desired value.