I have a class "Hospitalization" which I need to Serialize as an XML string. That class has a property "ActiveDiagnoses" which is a list of type "DiagnosisCode".
In that collection, only the elements with the property Order with a value of less than three should be included in the serialized string.
Here is an example (which fails to only serialize the DiagnosisCodes with an order less than 3):
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
namespace XmlConditionalSerializationOnListExample
{
[XmlRoot]
public class Hospitalization
{
public string PatientName { get; set; }
public DateTime AdmitDate { get; set; }
[XmlElement("DiagnosisCode")]
public List<DiagnosisCode> ActiveDiagnoses { get; set; }
}
public class DiagnosisCode
{
public string Code { get; set; }
public string CodeSet { get; set; }
[XmlIgnore]
public int Order { get; set; }
}
class Program
{
static void Main(string[] args)
{
Hospitalization hospitalization = new Hospitalization() { PatientName = "Test Patient", AdmitDate = DateTime.Now.Date };
List<DiagnosisCode> Dxs = new List<DiagnosisCode>()
{
new DiagnosisCode(){Code="Z99.81", CodeSet="ICD10", Order = 1}
,new DiagnosisCode(){Code="Z99.0", CodeSet="ICD10", Order = 2}
,new DiagnosisCode(){Code="Z98.5", CodeSet="ICD10", Order = 3}
};
hospitalization.ActiveDiagnoses = Dxs;
string HospitalizationXml = String.Empty;
XmlSerializer Ser = new XmlSerializer(hospitalization.GetType());
//XmlSerializer Ser = new XmlSerializer(Hospitalization);
using (StringWriter writer = new StringWriter())
{
Ser.Serialize(writer, hospitalization);
HospitalizationXml = writer.ToString();
}
Console.WriteLine("Hospitalization object as represented by XML string:\n{0}", HospitalizationXml);
Console.ReadKey();
}
}
}
My first thought was to set change the line where I assign the Dxs variable as the value for the ActiveDiagnoses property with a foreach loop which would conditionally add an XmlIgnore attribute to each DiagnosisCode with an order property value above 2 but apparently you aren't able to do that dynamically.
I then found a couple of examples of people using ShouldSerialize() Methods to determine whether or not a property would be serialized:
The difference between my scenario and the ones linked above is that Example 1 adds a ShouldSerialize() method for a property which isn't a List and although the second does add the ShouldSerialize() method for a List property, that method determines weather or not the entire list of elements is serialized, not particular elements within it.
I attempted to add the following method to the DiagnosisCode class:
public bool ShouldSerializeDiagnosisCode()
{
return Order < 3 ? true : false;
}
However it had no effect. I tried to move that method to the Hospitalization class but got a compile error as would be expected because the compiler doesn't know what I'm referring to with the Order property.
I did end up with a workaround by doing the following:
1: Change the Hospitalization class to have two lists of DiagnosisCode objects, where one of them is marked as to be ignored when serializing as XML.
[XmlRoot]
public class Hospitalization
{
public string PatientName { get; set; }
public DateTime AdmitDate { get; set; }
[XmlElement("DiagnosisCode")]
public List<DiagnosisCode> ActiveDiagnoses { get; set; }
[XmlIgnore]
public List<DiagnosisCode> NonBillableDiagnoses { get; set; }
}
2: Change my Main() method to add each diagnosis in a loop and determine which of the two Lists to add the DiagnosisCode to based on its OrderIndex at that point in time.
//hospitalization.ActiveDiagnoses = Dxs;
hospitalization.ActiveDiagnoses = new List<DiagnosisCode>();
hospitalization.NonBillableDiagnoses = new List<DiagnosisCode>();
foreach (DiagnosisCode dx in Dxs)
{
if (dx.Order < 3)
{
hospitalization.ActiveDiagnoses.Add(dx);
}
else
{
hospitalization.NonBillableDiagnoses.Add(dx);
}
}
That solution works ok but I'd like to know if there's a way where I could use the ShouldSerialize method in the way I intended as described above.
Any help/ suggestions you can provide I'd greatly appreciate.