C#
- Salvando,
Lendo e consultando informações em um arquivo XML (revisão)
![]() |
Neste artigo eu vou recordar como podemos salvar, ler e consultar informações em um arquivo XML usando a linguagem C# usando o Visual Studio 2013 for Windows Desktop. |
Nem sempre você vai precisar de um banco de dados relacional para guardar informações.
Os bancos de dados relacionais são uma das melhores opções quando o objetivo é armazenar e recuperar informações, mas existem situações na qual você pode usar outro recurso para este objetivo.
Se o seu caso não requer a utilização de um banco de dados, considere armazenar informações em arquivos XML. Eles são simples e fáceis de tratar e utilizar, usando os recursos da plataforma .NET.
As perspectivas do armazenamento de dados no formato XML são surpreendentes, e, até mesmo os Data WareHouses já estão armazenando informações no formato XML.
![]() |
Os namespaces System.Xml , System.Xml.Linq e System.Data.Linq fornecem um arsenal de classes que podemos usar para tratar informações em arquivos XML e neste projeto iremos usar algumas dessas classes.
Recursos usados:
Criando o projeto no Visual Studio 2013 Express for Windows Desktop
Abra o VS Express 2013 for Windows Desktop e clique em New Project;
A seguir selecione a linguagem Visual C# e o template Windows Forms Application;
Informe o nome XML_BD e clique no botão OK;
![]() |
Vamos agora criar uma pasta chamada Dados em nosso projeto para conter nosso arquivo XML chamado Produtos.xml.
Selecione o projeto e no menu PROJECT clique em New Folder informando o nome Dados;
A seguir clique com o botão direito do mouse sobre a pasta Dados e a seguir clique em Add New Item;
Selecione o template XML File e informe o nome Produtos.xml e defina a seguinte estrutura para o arquivo XML:
![]() |
Vamos criar também uma classe chamada Produto que irá representar um produto. Para isso selecione a pasta Dados e no menu PROJECT clique em Add Class;
Selecione o template Class e informe o nome Produto.cs digitando a seguir o código abaixo nesta classe:
public class Produto
{
public int Codigo { get; set; }
public string Nome { get; set; }
public decimal Preco { get; set; }
public int Estoque { get; set; }
public string Descricao { get; set; }
}
|
A seguir selecione o formulário padrão form1.vb e inclua, a partir da ToolBox, os seguintes controles:
5 TextBox : txtCodigoProduto, txtNomeProduto, txtPreco, txtEstoque e txtDescricao
1 Button : btnLocalizar , Text = Localizar
1 LisbBox : lbProdutos
4 Button : btnSalvar, btnNovo, btnCarregar e btnListarProdutos
Disponha os controles no formulário conforme a figura abaixo:
Vamos agora implementar as funcionalidades do nosso projeto.
Iniciando com a definindo dos namespaces usados no projeto:
using System;
using System.Data;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
using XML_BD.Dados;
using System.Linq;
E coma definição da variável caminho que retorna o caminho do diretório base que o resolvedor do Assembly usa para sondar os assemblies.
No nosso exemplo o retorno será : = "C:\\_csharp\\XML_BD\\XML_BD\\bin\\Debug\\"
String caminho = AppDomain.CurrentDomain.BaseDirectory;
Vamos usar essa variável para obter o caminho do arquivo Produtos.xml na pasta Dados do projeto usando o método estático CaminhoDadosXML() cujo código vemos abaixo:
public static string CaminhoDadosXML(string caminho)
{
if (caminho.IndexOf("\\bin\\Debug") != 0)
{
caminho = caminho.Replace("\\bin\\Debug", "");
}
return caminho;
}
|
O retorno será o caminho : "C:\\_csharp\\XML_BD\\XML_BD\"
Quando o formulário é carregado o evento Load do mesmo é executado e neste momento desabilitamos o botão Salvar:
private void Form1_Load(object sender, EventArgs e)
{
btnSalvar.Enabled = false;
}
|
1 - Criando um novo elemento <Produto> no XML
Para criar um novo item no arquivo XML o usuário deve clicar no botão Novo cujo código é visto a seguir:
private void btnNovo_Click(object sender, EventArgs e)
{
LimparTextBox(this);
btnSalvar.Enabled = true;
txtCodigoProduto.Text = Convert.ToString(GetRandomNumber(1, 9999));
txtNomeProduto.Focus();
}
|
Este código limpa todos os controles TextBox do formulário e habilita o botão Salvar. A seguir é gerado um número aleatório para o código do projeto e o foco é posto na caixa de texto txtNomeProduto.
A seguir temos o código da rotina LimparTextBox() que limpa os controles TextBox:
void LimparTextBox(Control con)
{
foreach (Control c in con.Controls)
{
if (c is TextBox)
((TextBox)c).Clear();
else
LimparTextBox(c);
}
}
|
E abaixo o código da rotina GetRandomNumber() que gera um número aleatório:
private static readonly Random getrandom = new Random();
private static readonly object syncLock = new object();
public static int GetRandomNumber(int min, int max)
{
lock (syncLock)
{ // sincroniza
return getrandom.Next(min, max);
}
}
|
2 - Salvando os dados do novo elemento <Produto> no XML
Após digitar os dados no formulário o usuário deverá clica no botão Salvar para persistir as informações do produto no arquivo Produtos.xml.
O código do evento Click do botão Salvar é dado a seguir:
private void btnSalvar_Click(object sender, EventArgs e)
{
try
{
using (DataSet dsResultado = new DataSet())
{
dsResultado.ReadXml(CaminhoDadosXML(caminho) + @"Dados\Produtos.xml");
if (dsResultado.Tables.Count == 0)
{
//cria uma instância do Produto e atribui valores às propriedades
Produto oProduto = new Produto();
oProduto.Codigo = Convert.ToInt32(txtCodigoProduto.Text);
oProduto.Nome = txtNomeProduto.Text;
oProduto.Preco = Convert.ToDecimal(txtPreco.Text);
oProduto.Estoque = Convert.ToInt32(txtEstoque.Text);
oProduto.Descricao = txtDescricao.Text;
XmlTextWriter writer = new XmlTextWriter(CaminhoDadosXML(caminho) + @"Dados\Produtos.xml", System.Text.Encoding.UTF8);
writer.WriteStartDocument(true);
writer.Formatting = Formatting.Indented;
writer.Indentation = 2;
writer.WriteStartElement("Produtos");
writer.WriteStartElement("Produto");
writer.WriteStartElement("Codigo");
writer.WriteString(oProduto.Codigo.ToString());
writer.WriteEndElement();
writer.WriteStartElement("Nome");
writer.WriteString(oProduto.Nome);
writer.WriteEndElement();
writer.WriteStartElement("Preco");
writer.WriteString(oProduto.Preco.ToString());
writer.WriteEndElement();
writer.WriteStartElement("Estoque");
writer.WriteString(oProduto.Estoque.ToString());
writer.WriteEndElement();
writer.WriteStartElement("Descricao");
writer.WriteString(oProduto.Descricao);
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Close();
dsResultado.ReadXml(CaminhoDadosXML(caminho) + @"Dados\Produtos.xml");
}
else
{
//inclui os dados no DataSet
dsResultado.Tables[0].Rows.Add(dsResultado.Tables[0].NewRow());
dsResultado.Tables[0].Rows[dsResultado.Tables[0].Rows.Count - 1]["Codigo"] = txtCodigoProduto.Text;
dsResultado.Tables[0].Rows[dsResultado.Tables[0].Rows.Count - 1]["Nome"] = txtNomeProduto.Text.ToUpper();
dsResultado.Tables[0].Rows[dsResultado.Tables[0].Rows.Count - 1]["Preco"] = txtPreco.Text;
dsResultado.Tables[0].Rows[dsResultado.Tables[0].Rows.Count - 1]["Estoque"] = txtEstoque.Text;
dsResultado.Tables[0].Rows[dsResultado.Tables[0].Rows.Count - 1]["Descricao"] = txtDescricao.Text;
dsResultado.AcceptChanges();
//-- Escreve para o arquivo XML final usando o método Write
dsResultado.WriteXml(CaminhoDadosXML(caminho) + @"Dados\Produtos.xml", XmlWriteMode.IgnoreSchema);
}
//exibe os dados no datagridivew
dgvDados.DataSource = dsResultado.Tables[0];
MessageBox.Show("Dados salvos com sucesso.");
}
}
catch (Exception ex)
{
MessageBox.Show("Erro " + ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
|
Este código usa o método ReadXml() do objeto DataSet para ler os dados do arquivo XML e a seguir usa a classe XmlTextWriter para escrever no arquivo XML os dados informados pelo usuário no formulário.
A classe XmlTextWriter fornece uma maneira rápida de gerar streams ou arquivos contendo dados XML em conformidade com a W3C Extensible Markup Language (XML) 1.0. Ela contém diversos métodos e propriedades que vão fazer todo o trabalho pesado para você na prática.
Para usar esta classe basta você usar os namespace System.Xml e criar um novo objeto XmlTextWriter; em seguida basta ir incluindo os elementos Xml que você deseja criar. A classe comporta métodos para incluir cada tipo de elemento em um arquivo XML. A seguir temos alguns destes métodos:
Método | Descrição |
WriterStartDocument | Escreve a declaração XML indicativa da versão XML (version "1.0") |
WriteEndDocument | Fecha qualquer elemento ou atributo aberto. |
Close | Fecha o stream. |
WriteDocType | Escreve a declaração DOCTYPE com o nome especificado e atributos opcionais. |
WriterStartElement | Escreve tag de inicio definida. |
WriteEndElement | Fecha um elemento. |
WriteFullEndElement | Fecha um elemento. |
WriteElementString | Escreve um elemento contendo um valor string. |
WriteStartAttribute | Escreve o início de um atributo. |
WriteEndAttribute | Fecha a chamada anterior de WriteStarttAttribute. |
WriterString | Escreve uma string. |
WriteAttributes | Escreve um atributo com um valor específico.. |
WriteCData | Escreve um bloco <![CDATA[...]]> contendo o texto especificado.. |
WriteComment | Escreve um comentário <!--...--> contendo o texto especificado. |
WriteWhitespace | Escreve um espaço. |
WriteProcessingInstruction | Escreve uma instrução de processamento com um espaço entre o nome e o texto seguido de <?name text?>. |
3 - Carregando dados do XML e exibindo no DataGridView
Para carregar dados do arquivo XML e exibir no controle DataGridView - dgvDados - o usuário clicar no botão Carregar - que tem o código abaixo:
private void btnCarregar_Click(object sender, EventArgs e)
{
GetDados();
}
|
Neste código apenas chamamos a rotina GetDados() que possui o código a seguir:
public void GetDados()
{
try
{
DataSet dsResultado = new DataSet();
dsResultado.ReadXml(CaminhoDadosXML(caminho) + @"Dados\Produtos.xml");
if (dsResultado.Tables.Count != 0)
{
if (dsResultado.Tables[0].Rows.Count > 0)
{
dgvDados.DataSource = dsResultado.Tables[0];
}
}
}
catch (Exception ex)
{
throw ex;
}
}
|
Neste código usamos o método ReadXML() do DataSet para obter os dados do arquivo Produtos.xml e preencher o DataSet exibindo-o a seguir no DataGridView.
4 - Obtendo uma lista de Produtos e exibindo no ListBox
Para obter uma lista de produtos e exibir os dados desejados no controle ListBox o usuário clica no botão - Listar Produtos - cujo código vemos abaixo:
private void btnListarProdutos_Click(object sender, EventArgs e)
{
XDocument doc = XDocument.Load((CaminhoDadosXML(caminho) + @"Dados\Produtos.xml"));
var prods = from p in doc.Descendants("Produto")
select new
{
NomeProduto = p.Element("Nome").Value,
PrecoProduto = p.Element("Preco").Value,
};
foreach (var p in prods)
{
lbProdutos.Items.Add( p.NomeProduto + " " + p.PrecoProduto);
}
}
|
O código realiza uma consulta LINQ no arquivo XML obtendo os elementos <Produto> e extrai as informações do Nome e Preço exibindo-as no ListBox.
5 - Localizando um produto pelo código e exibindo no formulário
Podemos localizar um produto pelo seu código clicando no botão Localizar() que tem o seguinte código:
private void btnLocalizarProduto_Click(object sender, EventArgs e)
{
// cria a consulta
var prods = from p in XElement.Load((CaminhoDadosXML(caminho) + @"Dados\Produtos.xml")).Elements("Produto")
where p.Element("Codigo").Value == txtCodigoProduto.Text
select new
{
NomeProduto = p.Element("Nome").Value,
PrecoProduto = p.Element("Preco").Value,
EstoqueProduto = p.Element("Estoque").Value,
DescricaoProduto = p.Element("Descricao").Value,
};
// Executa a consulta
foreach (var produto in prods)
{
txtNomeProduto.Text = produto.NomeProduto;
txtPreco.Text = produto.PrecoProduto;
txtEstoque.Text = produto.EstoqueProduto;
txtDescricao.Text = produto.DescricaoProduto;
}
}
|
Este código realiza um consulta LINQ pelo elemento <Codigo> usando o valor do código do produto informado. A seguir extrai as informações e exibe nas caixas de texto do formulário.
6 - Selecionando uma linha do DataGridView e exibindo os valores no formulário
Após carregar o controle DataGridView com dados do arquivo Produtos.xml podemos selecionar uma linha específica e exibir os seus detalhes nas caixas de texto do formulário.
Para isso usamos o evento CellClick do DataGridView obtendo os valores das células da linha selecionada e exibindo-os nas caixas de texto. O código é dado a seguir:
private void dgvDados_CellClick(object sender, DataGridViewCellEventArgs e)
{
try
{
//obtem o valor das células do grid
txtCodigoProduto.Text = dgvDados.CurrentRow.Cells[0].Value.ToString();
txtNomeProduto.Text = dgvDados.CurrentRow.Cells[1].Value.ToString();
txtPreco.Text = dgvDados.CurrentRow.Cells[2].Value.ToString();
txtEstoque.Text = dgvDados.CurrentRow.Cells[3].Value.ToString();
txtDescricao.Text = dgvDados.CurrentRow.Cells[4].Value.ToString();
}
catch
{ }
}
|
Executando o projeto, incluindo algumas informações, carregando e listando os produtos teremos o seguinte resultado:
![]() |
Pegue o projeto
completo aqui:
XML_BD.zip
Porque nem mesmo seus irmãos criam nele.
Disse-lhes, pois, Jesus: Ainda não é chegado o meu tempo, mas
o vosso tempo sempre está pronto.
O mundo não vos pode odiar, mas ele me odeia a mim, porquanto
dele testifico que as suas obras são más.
João 7:5-7
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Gostou ?
Compartilhe no Facebook
Compartilhe no Twitter
Referências: