Catering for NULL values when reading XML

by Dominic Zukiewicz 21. February 2008 12:57
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();
        }
    }
}

Tags:

Xml

Powered by BlogEngine.NET 1.5.0.7
Theme by Interakting

Interakting

A full service digital agency offering online strategy, design and usability, systems integration and online marketing services that deliver real business benefits and ensure your online objectives are met.

Calendar

<<  February 2012  >>
MoTuWeThFrSaSu
303112345
6789101112
13141516171819
20212223242526
2728291234
567891011

View posts in large calendar