I get xml from a third party and I need to deserialize it to a C # object. This xml can contain attributes with an integer value or an empty value: attr = "11" or attr = ". I want to deserialize this attribute value in a property with an integer integer value type. But XmlSerializer does not support deserialization into types with a zero value. The following test the code crashes while creating an XmlSerializer with InvalidOperationException {"An error occurred reflecting the type" TestConsoleApplication.SerializeMe ".}.
[XmlRoot("root")] public class SerializeMe { [XmlElement("element")] public Element Element { get; set; } } public class Element { [XmlAttribute("attr")] public int? Value { get; set; } } class Program { static void Main(string[] args) { string xml = "<root><element attr=''>valE</element></root>"; var deserializer = new XmlSerializer(typeof(SerializeMe)); Stream xmlStream = new MemoryStream(Encoding.ASCII.GetBytes(xml)); var result = (SerializeMe)deserializer.Deserialize(xmlStream); } }
When I change the property type of Value to int, deserialization fails with an InvalidOperationException:
There is an error in the XML document (1, 16).
Can someone advise how to deserialize an attribute with an empty value into a nullable type (like null) while deserializing a non-empty attribute value into an integer? Is there any trick for this, so I donβt have to do deserialization of each field manually (there are actually a lot of them)?
Update after comment from ahsteele:
Xsi: nil attribute
As far as I know, this attribute only works with XmlElementAttribute - this attribute indicates that the element has no content, whether it be child elements or body text. But I need to find a solution for XmlAttributeAttribute. In any case, I can not change the xml, because I can not control it.
bool * Set property
This property only works when the attribute value is not empty or when the attribute is absent. When attr is empty (attr = ``), the XmlSerializer constructor fails (as expected).
public class Element { [XmlAttribute("attr")] public int Value { get; set; } [XmlIgnore] public bool ValueSpecified; }
Custom Nullable Class, as in this blog by Alex Scordellis
I tried to take the class from this blog post into my problem:
[XmlAttribute("attr")] public NullableInt Value { get; set; }
But the XmlSerializer constructor does not work with InvalidOperationException:
Cannot serialize the value element of type TestConsoleApplication.NullableInt.
XmlAttribute / XmlText cannot be used to encode types that implement IXmlSerializable}
An ugly surrogate solution (I am ashamed for me that I wrote this code here :)):
public class Element { [XmlAttribute("attr")] public string SetValue { get; set; } public int? GetValue() { if ( string.IsNullOrEmpty(SetValue) || SetValue.Trim().Length <= 0 ) return null; int result; if (int.TryParse(SetValue, out result)) return result; return null; } }
But I do not want to come up with a solution like this because it violates the interface of my class for its consumers. I'd rather manually implement the IXmlSerializable interface.
Currently, it looks like I should implement IXmlSerializable for the whole Element class (it's big), and there is no simple workaround ...
Alex Kliuchnikau Aug 18 '09 at 18:35 2009-08-18 18:35
source share