Today, I had a quick look at the problems associated with missing tags in XML.
If you are expecting a numeric value and the tag is missing, you'll get (in the case of int), a default to 0. This, of course happens as the assignment never takes place, and when displaying the data, is just reading the compiler assigned default of 0.
Now, lets take this a step further, and say you want to cater for it when it is missing, i.e. NULL - how do you do that?
The wonderful XmlSerializer will assign a XXXSpecified property with a boolean, when the tag is present. You must have declared this property, but once it is there, you can check it to see if it was specified. Even if you don't create this property, you'll still have the option of using the Nullable<> generic to help you on your way. This is the code I used to see it in action:
<!-- Customers.xml -->
<?xml version="1.0"?>
<Customers>
<Customer>
<Name>Dominic</Name>
<Age>25</Age>
<DateOfBirth>1982-01-01</DateOfBirth>
</Customer>
<Customer>
<Name>Louise</Name>
<Age>28</Age>
<DateOfBirth>1979-01-01</DateOfBirth>
</Customer>
</Customers>
//Customers.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
namespace XmlDeserialization
{
[XmlRoot("Customers")]
public class Customers
{
private Customer[] customer;
[XmlElement("Customer")]
public Customer[] Customer
{
get { return customer; }
set { customer = value; }
}
}
[XmlRoot("Customer")]
public class Customer
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
private Nullable<int> age;
public Nullable<int> Age
{
get { return age; }
set { age = value; }
}
private bool ageSpecified;
[XmlIgnore()]
public bool AgeSpecified
{
get { return ageSpecified; }
set { ageSpecified = value; }
}
private DateTime dateOfBirth;
public DateTime DateOfBirth
{
get { return dateOfBirth; }
set { dateOfBirth = value; }
}
}
}
//Program.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Diagnostics;
namespace XmlDeserialization
{
class Program
{
static void Main(string[] args)
{
XmlSerializer xmlSer = new XmlSerializer(typeof(Customers));
object graph = xmlSer.Deserialize(File.OpenText("Customers.xml"));
Customers c = graph as Customers;
Debug.Assert(c != null);
foreach (Customer cust in c.Customer)
{
if(cust.AgeSpecified)
Console.WriteLine("Name: {0}, Age: {1}, DateOfBirth: {2}", cust.Name, cust.Age, cust.DateOfBirth);
else
Console.WriteLine("Name: {0}, Age: N/A, DateOfBirth: {1}", cust.Name, cust.DateOfBirth);
}
Console.Read();
}
}
}