using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using smo = Microsoft.SqlServer.Management.Smo;
using System.Data;
using System.Xml;
namespace SmoHierarchy
{
    class Program
    {
        static void CheckForParent(Type type)
        {
            PropertyInfo pinfo = type.GetProperty("Parent");
            if (pinfo == null)
            {
                Console.WriteLine("No parent " + type.Name);
            }
        }
        static void AddChildren(XmlElement e, Type type)
        {
            XmlDocument od = e.OwnerDocument;
            foreach (PropertyInfo pinfo in type.GetProperties())
            {
                Type pType = pinfo.PropertyType;
                // skip Parent property, only go down the hierarchy
                if (pinfo.Name == "Parent") continue;
                if (pType.IsSubclassOf(
                    typeof(smo.SqlSmoObject)))
                {
                    CheckForParent(pType);
                    XmlElement child = (XmlElement)e.AppendChild(
                       od.CreateElement(pType.Name));
                    XmlAttribute name = 
                        child.Attributes.Append(od.CreateAttribute("name"));
                    name.Value = pinfo.Name;
                    AddChildren(child, pType);
                }
                if (pType.IsSubclassOf(
                    typeof(smo.AbstractCollectionBase)))
                {
                    CheckForParent(pType);
                    Type[] parameters = new Type[] { typeof(Int32) };
                    PropertyInfo itemInfo = 
                        pType.GetProperty("Item", parameters);
                    if (itemInfo != null)
                    {
                        XmlElement child = (XmlElement)e.AppendChild(
                            od.CreateElement(pType.Name));
                        XmlAttribute name = child.Attributes.Append(
                            od.CreateAttribute("name"));
                        name.Value = pinfo.Name;
                        child = (XmlElement)child.AppendChild(
                            od.CreateElement(itemInfo.PropertyType.Name));
                        AddChildren(child, itemInfo.PropertyType);
                        CheckForParent(itemInfo.PropertyType);
                    }
                }
            }
        }
        static void Main(string[] args)
        {
            XmlDocument xdoc = new XmlDocument();
            XmlElement serverElement = (XmlElement)xdoc.AppendChild(
                xdoc.CreateElement("Server"));
            Type server = typeof(smo.Server);
            AddChildren(serverElement, server);
            XmlTextWriter xwtr = new XmlTextWriter(
                "SmoHierarchy.xml", System.Text.Encoding.UTF8);
            xwtr.Formatting = Formatting.Indented;
            xdoc.Save(xwtr);
            xwtr.Close();
        }
    }
}
