Trying to deserialize some xml snippits from a vendor into objects. The problem is that I\'m getting an invalid format on every empy element tag. I can deserialize the obj
The most uniform way to clean out these nodes appears to be to add a RegEx filter to the deserializer.
public static T Deserialize<T>(string xml){ XmlSerializer xs = new XmlSerializer(typeof(T)); string cleanXml = Regex.Replace(xml, @"<[a-zA-Z].[^(><.)]+/>", new MatchEvaluator(RemoveText)); MemoryStream memoryStream = new MemoryStream((new UTF8Encoding()).GetBytes(cleanXml)); XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8); return (T)xs.Deserialize(memoryStream); }
static string RemoveText(Match m) { return "";}
See this article: Can XmlSerializer deserialize into a Nullable?
In a nutshell your Xml should look like this if you want to use Nullable types:
<foo xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
<propOne>1</propOne>
<propTwo xsi:nil='true'/>
</foo>
The two changes are adding the namespace, and explicitly setting xsi:nil to true on the null element.
If you don't have control over your Xml there is a more advanced technique described here: Using XmlSerializer to deserialize into a Nullable
For simplicity, why don't you parse the xml explictly using XmlDocument and XPath? Use XPath to explictly access each xml node e.g.
XmlNode node = xml.SelectSingleNode ("foo/PropOne");
if (node != null)
{
propOneValue = node.innerText;
}
Another option if you've not got control over the inbound XML is to work around this by having the deserializer pretend that the variable is a string:
[Serializable()]
public class foo
{
public foo(){}
[XmlElement("propOne")]
[EditorBrowsable(EditorBrowsableState.Never)]
public string propOneString {get;set;}
[XmlIgnore]
private int? propOneInternal = null;
[XmlIgnore]
private bool propOneSet = false;
[XmlIgnore]
public int? propOne
{
get
{
if (!propOneSet)
{
if(!string.IsNullOrEmpty(propOneString)
{
propOneInternal = int.Parse(propOneString);
}
//else leave as pre-set default: null
propOneSet = true;
}
return propOneInternal;
}
set { propOneInternal = value; }
}
}
The Deserialiser is happy to parse a string element when it's empty, so you make use of that.
It's not particularly nice, but it'll do if you've only got one or 2 tags to cover