Solucionado (ver solução)
Solucionado
(ver solução)
9
respostas

Obter conteúdo de um XML

Tenho um XML nesse formato:

<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">
    <channel>
        <url>
            <![CDATA[ http://portal.cfm.org.br/ ]]>
        </url>
        <total>4</total>
        <status>true</status>
        <mensagem/>
        <api_limite>100</api_limite>
        <api_consultas>7</api_consultas>
        <item>
            <tipo>CRM</tipo>
            <numero>30828</numero>
            <nome>MALCON ANDRADE LOPES</nome>
            <uf>MG</uf>
            <profissao/>
            <situacao>Ativo</situacao>
        </item>
        <item>
            <tipo>CRM</tipo>
            <numero>30828</numero>
            <nome>NISE MAGALHAES DA SILVEIRA</nome>
            <uf>RJ</uf>
            <profissao/>
            <situacao>Falecido</situacao>
        </item>
        <item>
            <tipo>CRM</tipo>
            <numero>30828</numero>
            <nome>FERNANDA CRISTINA ILHA ALGARVE</nome>
            <uf>RS</uf>
            <profissao>ANESTESIOLOGIA</profissao>
            <situacao>Ativo</situacao>
        </item>
        <item>
            <tipo>CRM</tipo>
            <numero>30828</numero>
            <nome>LUIZ CARLOS SILVEIRA MONTEIRO</nome>
            <uf>SP</uf>
            <profissao>CIRURGIA PEDIÁTRICA</profissao>
            <situacao>Ativo</situacao>
        </item>
    </channel>
</rss>

Criei uma classe para poder ler e armazenar o conteúdo , ficou assim:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Xml;

namespace DesignPatterns
{
    public class CRM
    {
        //-- Conteudo básico do XML
        string caminho;
        int total;
        bool status;
        string mensagem;
        int api_limite;
        int api_consultas;

        //-- Verificar qual tipo do texto
        bool lTotal = false;
        bool lStatus = false;
        bool lMensagem = false;
        bool lApi_limite = false;
        bool lApi_consultas = false;
        bool lTipo = false;
        bool lNumero = false;
        bool lNome = false;
        bool lUF = false;
        bool lProfissao = false;
        bool lSituacao = false;

        //-- Itens do XML
        List<ItemCRM> listaCRM;

        public CRM(string caminhoXML)
        {
            this.caminho = caminhoXML;

            listaCRM = new List<ItemCRM>();

            if (LerXML())
            {
                MessageBox.Show("XML lido com sucesso.");
            }else
            {
                MessageBox.Show("Erro ao ler o XML.");
            }

        }

        public string SituacaoCRM(string UF)
        {
            foreach (ItemCRM medico in listaCRM)
            {
                if (UF.Equals(medico.uf))
                {
                    return medico.situacao;

                }
            }

            return "Não encontrado";
        }

        public bool LerXML()
        {

            //-- Verificar se o arquivo existe
            if (!File.Exists(this.caminho))
            {
                return false;
            }

            //-- Criar objeto para leitura
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.DtdProcessing = DtdProcessing.Parse;
            XmlReader reader = XmlReader.Create(this.caminho, settings);

            reader.MoveToContent();

            //-- Parse the file and display each of the nodes.
            while (reader.Read())
            {
                switch (reader.NodeType)
                {
                    //-- Verificar cabeçalho
                    case XmlNodeType.Element:

                        //-- Limpar flags
                        this.lTotal = false;
                        this.lStatus = false;
                        this.lMensagem = false;
                        this.lApi_limite = false;
                        this.lApi_consultas = false;
                        this.lTipo = false;
                        this.lNumero = false;
                        this.lNome = false;
                        this.lUF = false;
                        this.lProfissao = false;
                        this.lSituacao = false;

                        if (reader.Name == "total")
                        {
                            this.lTotal = true;
                        }else if (reader.Name == "status")
                        {
                            this.lStatus = true;
                        }else if (reader.Name == "mensagem")
                        {
                            this.lMensagem = true;
                        }else if (reader.Name == "api_limite")
                        {
                            this.lApi_limite = true;
                        }else if (reader.Name == "api_consultas")
                        {
                            this.lApi_consultas = true;
                        }else if (reader.Name == "item")
                        {
                            this.listaCRM.Add(new ItemCRM());
                        }else if (reader.Name == "tipo")
                        {
                            this.lTipo = true;
                        }else if (reader.Name == "numero")
                        {
                            this.lNumero = true;
                        }else if (reader.Name == "nome")
                        {
                            this.lNome = true;
                        }else if (reader.Name == "uf")
                        {
                            this.lUF = true;
                        }else if (reader.Name == "profissao")
                        {
                            this.lProfissao = true;
                        }else if (reader.Name == "situacao")
                        {
                            this.lSituacao = true;
                        }

                        break;

                    //-- Salvar conteúdo de acordo com o cabeçalho
                    case XmlNodeType.Text:

                        if (this.lTotal)
                        {
                            this.total = Convert.ToInt16(reader.Value);
                        }else if (this.lStatus)
                        {
                            this.status = Convert.ToBoolean(reader.Value);
                        }else if (this.lMensagem)
                        {
                            this.mensagem = reader.Value;
                        }else if (this.lApi_limite)
                        {
                            this.api_limite = Convert.ToInt16(reader.Value);
                        }else if (this.lApi_consultas)
                        {
                            this.api_consultas = Convert.ToInt16(reader.Value);
                        }else if (this.lApi_consultas)
                        {
                            this.api_consultas = Convert.ToInt16(reader.Value);
                        }else if (this.lTipo)
                        {
                            this.listaCRM[this.listaCRM.Count - 1].tipo = reader.Value;
                        }else if (this.lNumero)
                        {
                            this.listaCRM[this.listaCRM.Count - 1].numero = Convert.ToInt16(reader.Value);
                        }else if (this.lNome)
                        {
                            this.listaCRM[this.listaCRM.Count - 1].nome = reader.Value;
                        }else if (this.lUF)
                        {
                            this.listaCRM[this.listaCRM.Count - 1].uf = reader.Value;
                        }else if (this.lProfissao)
                        {
                            this.listaCRM[this.listaCRM.Count - 1].profissao = reader.Value;
                        }else if (this.lSituacao)
                        {
                            this.listaCRM[this.listaCRM.Count - 1].situacao = reader.Value;
                        }

                        break;
                }
            }

            return true;
        }
    }

    public class ItemCRM
    {
        public string tipo = "";
        public int numero = 0;
        public string nome = "";
        public string uf = "";
        public string profissao = "";
        public string situacao = "";
    }
}

Estou chamando assim:

            CRM objCRM = new CRM(@"C:\CRM_Retorno.xml");
            MessageBox.Show(objCRM.SituacaoCRM("RJ"));

Não gostei de como ficou pois ficou muito complexo, tem algum modo mais simples?

9 respostas
solução!

Oi, Samir.

Eu estou no trabalho e sem meu ambiente do Windows para fazer testes, então eu meio que vou às cegas para tentar te ajudar com algumas pesquisas que fiz. Chegando em casa eu posso te ajudar melhor.

Tem como fazer de forma mais elegante que isso sim. É a classe XmlSerializer do .NET. Para cada nó do seu XML, você vai criar uma classe. Veja o seu caso:

<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">
    <channel>
        <url>
            <![CDATA[ http://portal.cfm.org.br/ ]]>
        </url>
        <total>4</total>
        <status>true</status>
        <mensagem/>
        <api_limite>100</api_limite>
        <api_consultas>7</api_consultas>
        <item>
            <tipo>CRM</tipo>
            <numero>30828</numero>
            <nome>MALCON ANDRADE LOPES</nome>
            <uf>MG</uf>
            <profissao/>
            <situacao>Ativo</situacao>
        </item>
        <item>
        (...)
    </channel>
</rss>

No seu caso, você vai ter, de cara, três classes:

  • Rss
  • Channel
  • Item

A classe Rss possuirá um atributo channel dentro dela e ficará da seguinte forma:

[XmlRoot("rss")]
public class Rss
{
    [XmlElement("channel")]
    public Channel channel { get; set; }
}

As anotações utilizadas na classe são do namespace System.Xml.Serialization. Você vai precisar usar esse namespace para funcionar.

E as outras classes também:

public class Channel
{
    [XmlElement("url")]
    public string Url { get; set; }

    [XmlElement("total")]
    public int Total { get; set; }

    [XmlElement("mensagem")]
    public string Mensagem { get; set; }

    [XmlElement("api_limite")]
    public int ApiLimite { get; set; }

    [XmlElement("api_consultas")]
    public int ApiConsultas { get; set; }

    [XmlElement("item")]
    public List<Item> Items { get; set; }
}

public class Item
{
    [XmlElement("tipo")]
    public string Tipo { get; set; }

    [XmlElement("numero")]
    public int Numero { get; set; }

    [XmlElement("nome")]
    public string Nome { get; set; }

    [XmlElement("uf")]
    public string Uf { get; set; }

    [XmlElement("profissao")]
    public string Profissao { get; set; }

    [XmlElement("situacao")]
    public string Situacao { get; set; }
}

Elas são as representações do seu XML em forma de Classes do .NET.

Para ler o seu XML:

XmlSerializer serializer = new XmlSerializer(typeof(Rss));
using (FileStream fileStream = new FileStream("C:\CRM_Retorno.xml", FileMode.Open)) 
{
    Rss result = (Rss) serializer.Deserialize(fileStream);
}

Espero que isso te ajude.

Referências:

XmlSerializer serializer = new XmlSerializer(typeof(Rss));
using (FileStream fileStream = new FileStream("C:\CRM_Retorno.xml", FileMode.Open)) 
{
    Rss result = (Rss) serializer.Deserialize(fileStream);
}

Esse trecho aqui está errado, pode me ajudar?

Qual é o erro?

Severity    Code    Description    Project    File    Line    Suppression State
Error    CS1002    ; expected    DesignPatterns    C:\Users\Samir\documents\visual studio 2015\Projects\DesignPatterns\DesignPatterns\WebserviceCRM.cs    16    Active
Error    CS1002    ; expected    DesignPatterns    C:\Users\Samir\documents\visual studio 2015\Projects\DesignPatterns\DesignPatterns\WebserviceCRM.cs    16    Active
Error    CS0116    A namespace cannot directly contain members such as fields or methods    DesignPatterns    C:\Users\Samir\documents\visual studio 2015\Projects\DesignPatterns\DesignPatterns\WebserviceCRM.cs    18    Active
Error    CS0103    The name 'fileStream' does not exist in the current context    DesignPatterns    C:\Users\Samir\documents\visual studio 2015\Projects\DesignPatterns\DesignPatterns\WebserviceCRM.cs    18    Active
Error    CS0103    The name 'serializer' does not exist in the current context    DesignPatterns    C:\Users\Samir\documents\visual studio 2015\Projects\DesignPatterns\DesignPatterns\WebserviceCRM.cs    18    Active
Error    CS1022    Type or namespace definition, or end-of-file expected    DesignPatterns    C:\Users\Samir\documents\visual studio 2015\Projects\DesignPatterns\DesignPatterns\WebserviceCRM.cs    16    Active
Error    CS1022    Type or namespace definition, or end-of-file expected    DesignPatterns    C:\Users\Samir\documents\visual studio 2015\Projects\DesignPatterns\DesignPatterns\WebserviceCRM.cs    16    Active
Error    CS1022    Type or namespace definition, or end-of-file expected    DesignPatterns    C:\Users\Samir\documents\visual studio 2015\Projects\DesignPatterns\DesignPatterns\WebserviceCRM.cs    70    Active
Error    CS1022    Type or namespace definition, or end-of-file expected    DesignPatterns    C:\Users\Samir\documents\visual studio 2015\Projects\DesignPatterns\DesignPatterns\WebserviceCRM.cs    71    Active
Error    CS1009    Unrecognized escape sequence    DesignPatterns    C:\Users\Samir\documents\visual studio 2015\Projects\DesignPatterns\DesignPatterns\WebserviceCRM.cs    16    Active
Error    CS1513    } expected    DesignPatterns    C:\Users\Samir\documents\visual studio 2015\Projects\DesignPatterns\DesignPatterns\WebserviceCRM.cs    15    Active

para parar de dar erro de compilação, o mais próximo que cheguei foi isso:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace DesignPatterns
{
    class WebserviceCRM
    {
        XmlSerializer serializer = new XmlSerializer(typeof(Rss));
        FileStream fileStream = new FileStream(@"C:\CRM_Retorno.xml", FileMode.Open);

        //Rss result = serializer.Deserialize(fileStream);
        Rss result;// = serializer.Deserialize(fileStream);

        [XmlRoot("rss")]
        public class Rss
        {
            [XmlElement("channel")]
            public Channel channel { get; set; }
        }

        public class Channel
        {
            [XmlElement("url")]
            public string Url { get; set; }

            [XmlElement("total")]
            public int Total { get; set; }

            [XmlElement("mensagem")]
            public string Mensagem { get; set; }

            [XmlElement("api_limite")]
            public int ApiLimite { get; set; }

            [XmlElement("api_consultas")]
            public int ApiConsultas { get; set; }

            [XmlElement("item")]
            public List<Item> Items { get; set; }
        }

        public class Item
        {
            [XmlElement("tipo")]
            public string Tipo { get; set; }

            [XmlElement("numero")]
            public int Numero { get; set; }

            [XmlElement("nome")]
            public string Nome { get; set; }

            [XmlElement("uf")]
            public string Uf { get; set; }

            [XmlElement("profissao")]
            public string Profissao { get; set; }

            [XmlElement("situacao")]
            public string Situacao { get; set; }
        }
        public bool LerRetorno()
        {
            bool resultado = false;

            Rss result = (Rss)serializer.Deserialize(fileStream);

            return resultado;
        }
    }
}

Consegui resolver, ficou assim:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace DesignPatterns
{
    public class WebserviceCRM
    {
        XmlSerializer serializer = new XmlSerializer(typeof(Rss));
        FileStream fileStream = new FileStream(@"C:\CSharp\CRM_Retorno.xml", FileMode.Open);

        //Rss result = serializer.Deserialize(fileStream);
        Rss result;// = serializer.Deserialize(fileStream);

        [XmlRoot("rss")]
        public class Rss
        {
            [XmlElement("channel")]
            public Channel channel { get; set; }
        }

        public class Channel
        {
            [XmlElement("url")]
            public string Url { get; set; }

            [XmlElement("total")]
            public int Total { get; set; }

            [XmlElement("mensagem")]
            public string Mensagem { get; set; }

            [XmlElement("api_limite")]
            public int ApiLimite { get; set; }

            [XmlElement("api_consultas")]
            public int ApiConsultas { get; set; }

            [XmlElement("item")]
            public List<Item> Items { get; set; }
        }

        public class Item
        {
            [XmlElement("tipo")]
            public string Tipo { get; set; }

            [XmlElement("numero")]
            public int Numero { get; set; }

            [XmlElement("nome")]
            public string Nome { get; set; }

            [XmlElement("uf")]
            public string Uf { get; set; }

            [XmlElement("profissao")]
            public string Profissao { get; set; }

            [XmlElement("situacao")]
            public string Situacao { get; set; }
        }
        public bool LerRetorno()
        {
            bool resultado = false;
            string mensagem = "";

            this.result = (Rss)serializer.Deserialize(fileStream);

            //MessageBox.Show("Total:" + this.result.channel.Total);

            mensagem += String.Format("Consultas efetuadas: {0} de {1}", this.result.channel.ApiConsultas, this.result.channel.ApiLimite)+"\n";

            foreach (Item CrmUf in this.result.channel.Items)
            {
                mensagem += String.Format("Status do CRM: {0} na UF: {1} é: {2} ", CrmUf.Numero, CrmUf.Uf, CrmUf.Situacao) +"\n";
            }

            MessageBox.Show(mensagem);

            return resultado;
        }
    }
}

Sensacional! O melhor de tudo foi você ter encontrado a resposta por si só. Eu só ajudei com um empurrãozinho de início rs.

Sensacional.

Obrigado Arthur, já tenho experiencia em outra linguagem ae facilita...

Se prestar atenção eu já vim com uma solução, mas era muito complexa.

Deu para perceber sim. Era só uma questão de você conhecer a API do .NET que trabalha com XML para facilitar. Só fiz apresentar isso mesmo. O resto foi tudo contigo :)