Jul 1, 2012

Como gerar xml à partir de uma classe com atributos customizados





Bom, esses dias precisei criar um XML a partir de uma classe, com os valores das propriedades do objeto.


Realmente existem diversos meios de se fazer isso facilmente, como serialização, entre outros.O problema era que apenas alguns atributos seriam adicionados, não a classe inteira e ainda por cima com nomes diferentes. Por exemplo:

Nome da propriedade "Nome" e nome do atributo xml era "nome_usuario".

Para isso criei um atributo customizado:





  [AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = false)]
    public class AtributoXml: Attribute
    {
        private string _nomeXml;
        public string NomeXml
        {
            get { return _nomeXml; }
            set { _nomeXml = value; }
        }
    }





Não esquecer de colocar o "AttributeTargets.Property" , já que assim é possível colocar nas propriedades e não apenas na classe.




No passo seguinte usaremos reflection para acessar dados do atributo e da classe, por isso não esqueça de referência  à "System.Reflection;"

Para conseguir pegar o valor do atributo ,utiliza-se o seguinte códig


var campos = tipo.GetProperties(BindingFlags.Public | BindingFlags.Instance);//Obtém propriedades
foreach (var c in campos)//percorre todos os campos
            {
                  var keys = c.GetCustomAttributes(typeof(AtributoXml), true); //Obtém atributo 
                  nomeCampo = ((AtributoXmlBaseMwl)(keys[0])).NomeXml;

            }


Aplicação real:


public virtual string CriarXml()
        {
            string xmlValue = "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>
            <config xmlns=\"http://www.w3schools.com\" 
            xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" 
            xsi:schemaLocation=\"http://www.w3schools.com\" ><item>";
            var tipo = typeof(BaseMwlItem);

            var campos = tipo.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (var c in campos)
            {
                // lista atributos do campo
                string nomeCampo = string.Empty;
                var keys = c.GetCustomAttributes(typeof(AtributoXmlBaseMwl), true);
                if (keys.Length == 1 && keys[0] is AtributoXmlBaseMwl)
                    nomeCampo = ((AtributoXmlBaseMwl)(keys[0])).NomeXml;

                if (!string.IsNullOrEmpty(nomeCampo))
                {
                    object valor = c.GetValue(this, null);
                    string valorPropriedade = string.Empty;
                    if (valor is DateTime)
                    {
                        if (nomeCampo.ToLower().Contains("time"))
                            valorPropriedade = ((DateTime)valor).ToString("hh:mm:ss");
                        else
                            valorPropriedade = ((DateTime)valor).ToString("yyyy-MM-dd");
                    }
                    else
                    {
                        valorPropriedade = valor.ToString();
                    }

                    xmlValue += string.Format("<{0}>{1}</{2}>", nomeCampo, 
                                valorPropriedade, nomeCampo);
                }
            }

            return xmlValue + "</item>";

        }




Pronto, faça o que quiser com seu XML.

Abraços
Rafael Campana


1 comment: