I have these 2 classes
[XmlType]
public class Child
{
public Child()
{
X = false;
Y = -100;
}
[XmlAttribute]
public bool X { get; set; }
[XmlAttribute]
public int Y { get; set; }
}
[XmlRoot]
public class Parent
{
public Parent()
{
C = new Child()
{
X = true;
}
;
}
[XmlElement]
public child C { get; set; }
}
when I try to parse a parent with child object that does not specify a value of x, I need x to be true not false. Example:
string xmlText = "<Parent><C y='1000'/></Parent>";
Parent p;
using (var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(xmlText)))
{
using (var reader = XmlDictionaryReader.CreateTextReader(memoryStream, Encoding.UTF8, XmlDictionaryReaderQuotas.Max, null))
{
var xmlDeserializer = new XmlSerializer(typeof(parent));
p = xmlDeserializer.Deserialize(reader) as Parent;
}
}
if(p.C.X)
{
Console.WriteLine("p.C.X is true");.
}
else
{
Console.WriteLine("p.C.X is false");
}
Then if we print p.C.X it will be false not true. How to solve this problem?
Note: I have updated the question, X was int in the beginning and then I changed it be bool (that's why the answers will refer to X as an int not a bool).
If there is no "invalid value", one solution I see is to use a boolean flag in the child class to indicate whether the X property was set or not.
This flag starts as true, but then is set to false in the X setter.
Then in the parent's C setter, you need to check that flag.
[XmlType]
public class Child
{
private int x;
public Child()
{
x = 10;
UsingDefaulXValue = true;
Y = -100;
}
[XmlAttribute]
public int X
{
get
{
return x;
}
set
{
x = value;
UsingDefaulXValue = false;
}
}
[XmlIgnore]
public bool UsingDefaulXValue { get; private set; }
[XmlAttribute]
public int Y { get; set; }
}
[XmlRoot]
public class Parent
{
private const int DefaultX = 5;
private Child c;
public Parent()
{
// Careful to use property and not field
C = new Child();
}
[XmlElement]
public Child C
{
get
{
return c;
}
set
{
c = value;
if (c.UsingDefaulXValue)
{
c.X = DefaultX;
}
}
}
}
Trying it out:
void Main()
{
// Checking the child's default value
Child c1 = Deserialize<Child>("<Child/>");
Console.WriteLine(c1.X); // it will print 10.
Child c2 = Deserialize<Child>("<Child X='30'/>");
Console.WriteLine(c2.X); // it will print 30.
// Checking the parent's default value
Parent p1 = Deserialize<Parent>("<Parent></Parent>");
Console.WriteLine(p1.C.X); // it will print 5.
Parent p2 = Deserialize<Parent>("<Parent><C Y='1000'/></Parent>");
Console.WriteLine(p2.C.X); // it will print 5.
Parent p3 = Deserialize<Parent>("<Parent><C X='20' Y='1000'/></Parent>");
Console.WriteLine(p3.C.X); // it will print 20.
}
T Deserialize<T>(string xmlText)
{
using (var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(xmlText)))
{
using (var reader = XmlDictionaryReader.CreateTextReader(memoryStream, Encoding.UTF8, XmlDictionaryReaderQuotas.Max, null))
{
var xmlDeserializer = new XmlSerializer(typeof(T));
return (T)xmlDeserializer.Deserialize(reader);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With