A solr result parser
Autor: Marco Minas | Publicado: 2013-07-03T18:31:00-07:00

The code
The sample starter class

using System;
using System.Text;

namespace mmcSolutions.SolrParser
{
    /// 
    /// 
    /// 
    public class Test
    {
        /// 
        /// 
        /// 
        public static void TestResultParser()
        {
            var file = @"D:\Projetos\Estudos\mmcSolutions.Parser\mmcSolutions.Parser\Sample\Employee.xml";
            var xml = System.IO.File.ReadAllText(file, Encoding.Unicode);
            var obj = ResultParser.Parse(xml);
        }
    }
}



The DTO sample class

using System;

namespace mmcSolutions.SolrParser
{
    /// 
    /// A sample Employee entity.
    /// 
    public class Employee
    {
        /// 
        /// Employee ID.
        /// 
        [SolrAttribute(Name = "id", Type = SolrType.String, isNullable = false)]
        public string ID { get; set; }
        /// 
        /// Name
        /// 
        [SolrAttribute(Name = "name", Type = SolrType.String, isNullable = false)]
        public string Name { get; set; }
        /// 
        /// E-mail
        /// 
        [SolrAttribute(Name = "email", Type = SolrType.String, isNullable = false)]
        public string Email { get; set; }
        /// 
        /// Hire date
        /// 
        [SolrAttribute(Name = "hiredate", Type = SolrType.Date, isNullable = false)]
        public DateTime HireDate { get; set; }
        /// 
        /// Address
        /// 
        [SolrAttribute(Name = "address", Type = SolrType.String, isNullable = false)]
        public string Address { get; set; }
        /// 
        /// Manager
        /// 
        [SolrAttribute(Name = "sallary", Type = SolrType.Float, isNullable = false)]
        public decimal Sallary { get; set; }
        /// 
        /// Status
        /// 
        [SolrAttribute(Name = "status", Type = SolrType.Short, isNullable = false)]
        public short Status { get; set; }

    }
}



Solr attribute

using System;

namespace mmcSolutions.SolrParser
{
    /// 
    /// 
    /// 
    [AttributeUsage(AttributeTargets.Property)]
    public sealed class SolrAttribute : System.Attribute
    {
        /// 
        /// Attribute class to be used with text file parser.
        /// 
        public SolrAttribute() : base() { }

        /// 
        /// The name of field.
        /// 
        public String Name { get; set; }
        /// 
        /// Specify Solr data type.
        /// 
        public SolrType Type { get; set; }
        /// 
        /// Specify if can be null
        /// 
        public bool isNullable { get; set; }

    }
}



Solr type enumerator

using System;

namespace mmcSolutions.SolrParser
{
    /// 
    /// 
    /// 
    public enum SolrType
    {
        /// 
        /// String solr type
        /// 
        String,
        /// 
        /// Array solr type
        /// 
        Array,
        /// 
        /// DateTime solr type
        /// 
        Date,
        /// 
        /// Int solr type
        /// 
        Int,
        /// 
        /// Short solr type
        /// 
        Short,
        /// 
        /// Long solr type
        /// 
        Long,
        /// 
        /// Decimal solr type
        /// 
        Decimal,
        /// 
        /// Double solr type
        /// 
        Double,
        /// 
        /// Float
        /// 
        Float
    }
}



The XElement extensions class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace mmcSolutions.SolrParser
{
    public static class XElementExtensions
    {
        public static string GetArray(this XElement e, string nodeName)
        {
            try { return GetValue(e, "array", nodeName); }
            catch { return string.Empty; }
        }
        public static string GetString(this XElement e, string nodeName)
        {
            try { return GetValue(e, "str", nodeName); }
            catch { return string.Empty; }
        }
        public static string GetText(this XElement e, string nodeName)
        {
            try { return GetValue(e, "text", nodeName); }
            catch { return string.Empty; }
        }

        public static DateTime GetDate(this XElement e, string nodeName)
        {
            try { return DateTime.Parse(GetValue(e, "date", nodeName)); }
            catch { return default(DateTime); }
        }
        public static DateTime? GetDateOrNull(this XElement e, string nodeName)
        {
            try { return DateTime.Parse(GetValue(e, "date", nodeName)); }
            catch { return null; }
        }

        public static bool GetBoolean(this XElement e, string nodeName)
        {
            try { return bool.Parse(GetValue(e, "boolean", nodeName)); }
            catch { return default(bool); }
        }
        public static bool? GetBooleanOrNull(this XElement e, string nodeName)
        {
            try { return bool.Parse(GetValue(e, "boolean", nodeName)); }
            catch { return null; }
        }

        public static short GetShort(this XElement e, string nodeName)
        {
            try { return short.Parse(GetValue(e, "short", nodeName)); }
            catch { return default(short); }
        }
        public static short? GetShortOrNull(this XElement e, string nodeName)
        {
            try { return short.Parse(GetValue(e, "short", nodeName)); }
            catch { return null; }
        }

        public static int GetInt(this XElement e, string nodeName)
        {
            try { return int.Parse(GetValue(e, "int", nodeName)); }
            catch { return default(short); }
        }
        public static int? GetIntOrNull(this XElement e, string nodeName)
        {
            try { return int.Parse(GetValue(e, "int", nodeName)); }
            catch { return null; }
        }

        public static long GetLong(this XElement e, string nodeName)
        {
            try { return short.Parse(GetValue(e, "long", nodeName)); }
            catch { return default(long); }
        }
        public static long? GetLongOrNull(this XElement e, string nodeName)
        {
            try { return long.Parse(GetValue(e, "long", nodeName)); }
            catch { return null; }
        }

        public static decimal GetDecimal(this XElement e, string nodeName)
        {
            try { return decimal.Parse(GetValue(e, "decimal", nodeName)); }
            catch { return default(decimal); }
        }
        public static decimal? GetDecimalOrNull(this XElement e, string nodeName)
        {
            try { return decimal.Parse(GetValue(e, "decimal", nodeName)); }
            catch { return null; }
        }

        public static double GetDouble(this XElement e, string nodeName)
        {
            try { return double.Parse(GetValue(e, "double", nodeName)); }
            catch { return default(double); }
        }
        public static double? GetDoubleOrNull(this XElement e, string nodeName)
        {
            try { return double.Parse(GetValue(e, "double", nodeName)); }
            catch { return null; }
        }

        public static float GetFloat(this XElement e, string nodeName)
        {
            try { return float.Parse(GetValue(e, "float", nodeName)); }
            catch { return default(float); }
        }
        public static float? GetFloatOrNull(this XElement e, string nodeName)
        {
            try { return float.Parse(GetValue(e, "float", nodeName)); }
            catch { return null; }
        }

        private static string GetValue(XElement e, string elementName, string nodeName)
        {
            return e.Elements(elementName).First(s => s.Attribute("name").Value.Equals(nodeName)).Value;
        }

    }
}



The XML employee sample


  employee#2008-09.001
  Marco Antonio Almeida
  marcominas@hotmail.com
  2008-09-01T00:00:00Z
  Rua Lourenco Vanucci Jardim Guaruja Sorocaba-SP
  1
  1234.56
  
    first skill
    second skill
  




The solr parser class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Xml.Linq;

namespace mmcSolutions.SolrParser
{
    /// 
    /// 
    /// 
    public class ResultParser
    {
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        public static T Parse(String xml)
        {
            var entity = Activator.CreateInstance();
            var properties = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public);
            foreach (PropertyInfo pi in properties)
            {
                try
                {
                    var objValue = GetObjectValue(pi, xml);
                    pi.SetValue(entity, Convert.ChangeType(objValue, pi.PropertyType), null);
                }
                finally { }
            }
            return entity;
        }

        private static object GetObjectValue(PropertyInfo pi, string xml)
        {
            var element = XDocument.Parse(xml).Descendants("doc");
            var attribute = GetAttribute(pi);
            
            switch (attribute.Type)
            {
                case SolrType.Array:
                    return element.Select(e => new { Value = e.GetArray(attribute.Name) }).ToList()[0].Value;

                case SolrType.Date:
                    if (attribute.isNullable)
                        return element.Select(e => new { Value = e.GetDateOrNull(attribute.Name) }).ToList()[0].Value;
                    else
                        return element.Select(e => new { Value = e.GetDate(attribute.Name) }).ToList()[0].Value;

                case SolrType.Decimal:
                    if (attribute.isNullable)
                        return element.Select(e => new { Value = e.GetDecimalOrNull(attribute.Name) }).ToList()[0].Value;
                    else
                        return element.Select(e => new { Value = e.GetDecimal(attribute.Name) }).ToList()[0].Value;

                case SolrType.Double:
                    if (attribute.isNullable)
                        return element.Select(e => new { Value = e.GetDoubleOrNull(attribute.Name) }).ToList()[0].Value;
                    else
                        return element.Select(e => new { Value = e.GetDouble(attribute.Name) }).ToList()[0].Value;

                case SolrType.Int:
                    if (attribute.isNullable)
                        return element.Select(e => new { Value = e.GetIntOrNull(attribute.Name) }).ToList()[0].Value;
                    else
                        return element.Select(e => new { Value = e.GetInt(attribute.Name) }).ToList()[0].Value;

                case SolrType.Long:
                    if (attribute.isNullable)
                        return element.Select(e => new { Value = e.GetLongOrNull(attribute.Name) }).ToList()[0].Value;
                    else
                        return element.Select(e => new { Value = e.GetLong(attribute.Name) }).ToList()[0].Value;

                case SolrType.Short:
                    if (attribute.isNullable)
                        return element.Select(e => new { Value = e.GetShortOrNull(attribute.Name) }).ToList()[0].Value;
                    else
                        return element.Select(e => new { Value = e.GetShort(attribute.Name) }).ToList()[0].Value;

                case SolrType.Float:
                    if (attribute.isNullable)
                        return element.Select(e => new { Value = e.GetFloatOrNull(attribute.Name) }).ToList()[0].Value;
                    else
                        return element.Select(e => new { Value = e.GetFloat(attribute.Name) }).ToList()[0].Value;

                case SolrType.String:
                    return element.Select(e => new { Value = e.GetString(attribute.Name) }).ToList()[0].Value;
            }

            return null;
        }
        private static T GetAttribute(PropertyInfo property)
        {
            foreach (object attribute in property.GetCustomAttributes(typeof(T), false))
                if (attribute is T)
                    return (T)attribute;
            return Activator.CreateInstance();
        }

    }
}


So, that´s it. Enjoy.