Manipulando documentos XML no C# – Parte III

Nos artigos anteriores vimos como manipular documentos XML usando as XMLTextReader e XMLTextWrite um pouco trabalhoso, nesse artigo irei demonstrar como manipular um documento XML usando o componente DataSet e também como criar o XML Schema.

O DataSet facilita a gravação e leitura de documentos XML e do XML Schema faz o trabalho bruto, assim com os métodos ReadXML, ReadXMLSchema, WriteXML e WriteXMLSchema pode-se fazer a leitura do XML e também a leitura do XML Schema para dentro do DataSet como pode-se fazer a gravação do documento XML e do XML Schema.

Após feita a leitura do documento e do XML Schema teremos o componente DataSet para manipular o XML qualquer alteração, inclusão ou exclusão dos dados quando chamado o método WriteXML será refletida no documento XML.

O propósito desse artigo não é mostrar que o XML irá substituir o uso de um banco de dados como o do SQL Server CE, na escolha devemos levar em consideração a quantidade de dados e outros fatores para decidir no uso de documento XML ou de um banco de dados, quando como nesse exemplo a quantidade de dados processados será baixa o XML vai dar conta tranquilamente.

Definição de XML Schema

A linguagem XML Schema é muito importante no uso de documentos XML com DataSet, XML Schema é um esquema XML que descreve a estrutura de um documento XML, define os elementos e atributos que são visíveis ou não, define os elementos que são filhos, se os elementos podem conter texto ou são vazies, os tipos de dados para elementos e atributos e os valores padrões ou fixo para os elementos e atributos essa seria uma simples definição do que é XML Schema ou também conhecidos como XML Schema Definition (XSD). O XML Schema é utilizado para validar um documento XML e também nos auxilia a entender como o documento XML é formado.

Crie um novo projeto em Visual C# usando o Template Smart Device Application na plataforma Pocket PC com Windows Forms como ilustra as Figuras 1 e 2.

 

 

Figura 1. Formulário de escolha da Linguagem e do nome do projeto

 

 

Figura 2. Formulário de escolha da plataforma e o tipo do projeto

Montando a Interface

Nesse exemplo usaremos um DataGrid para exibir os dados oriundos do DataSet, dois TextBox que seram usados para alterar os valores dos registros do DataSet, três botões um para criar um novo registro no DataSet, outro para gravar as alterações feitas no registros no Dataset e o último para gravar o documento XML e dois Label, distribua os controles no formulário principal do projeto.

Quando é criado um novo projeto automaticamente é inserido nesse projeto um controle MainMenu no projeto, insira um novo MenuItem no MainMenu chamado Sair ele será responsável por finalizar a nossa aplicação Pocket PC, a implementação do evento Click do MenuItem será implementado mais a diante nesse artigo. A Listagem 1 demonstra as propriedades dos controle que foram alteradas.

 

Controle

Propriedade

Valor

Label1

Text

Nome

Label2

Text

Telefone

TextBox1

Name

txtNome

TextBox2

Name

txtTelefone

Button1

Text

Novo

Button1

Name

btnNovo

Button2

Text

Gravar

Button2

Name

btnGravar

Button3

Text

Salvar XML

Button3

Name

btnSalvar

 

Após as feitas as alterações nas propriedades dos controles a interface do projeto deve ficar parecida com a exibida na Figura 3.

 

 

Figura 3. Interface Gráfica do projeto Pocket PC

Implementando e entendendo o Código Fonte

O documento XML que será usado nesse artigo é bem simples, contendo três campos (Código, Nome e Telefone), duas constantes contendo o caminho do documento XML(caminhoXML) e do XML Schema(caminhoXSD) dois métodos um chamado GeraXML e outro CarregaXML e uma variável global do tipo DataSet(dsXML) que contém os dados do documento XML. Veja o código fonte do projeto na Listagem 1.

 

Listagem 1. Código fonte do Projeto

using System;

using System.Drawing;

using System.Collections;

using System.Windows.Forms;

using System.Data;

using System.IO;

 

namespace PCDataSet

{

       public class Form1 : System.Windows.Forms.Form

       {

             private System.Windows.Forms.MainMenu mainMenu1;

             private System.Windows.Forms.DataGrid dataGrid1;

             private System.Windows.Forms.Label label1;

             private System.Windows.Forms.TextBox txtNome;

             private System.Windows.Forms.Label label2;

             private System.Windows.Forms.TextBox txtTelefone;

             private System.Windows.Forms.MenuItem menuItem1;

             private System.Windows.Forms.Button btnNovo;

             private System.Windows.Forms.Button btnSalvar;

             private System.Windows.Forms.Button btnGravar;

             private DataSet dsXML;

            

             private const string caminhoXML = "\\Program Files\\PCDataSet\\Dados.xml";

             private const string caminhoXSD = "\\Program Files\\PCDataSet\\Dados.xsd";

            

             public Form1()

             {

                    InitializeComponent();

             }

             protected override void Dispose( bool disposing )

             {

                    base.Dispose( disposing );

             }

             #region Windows Form Designer generated code

             private void InitializeComponent()

             {

                    this.mainMenu1 = new System.Windows.Forms.MainMenu();

                    this.menuItem1 = new System.Windows.Forms.MenuItem();

                    this.dataGrid1 = new System.Windows.Forms.DataGrid();

                    this.label1 = new System.Windows.Forms.Label();

                    this.txtNome = new System.Windows.Forms.TextBox();

                    this.txtTelefone = new System.Windows.Forms.TextBox();

                    this.label2 = new System.Windows.Forms.Label();

                    this.btnNovo = new System.Windows.Forms.Button();

                    this.btnSalvar = new System.Windows.Forms.Button();

                    this.btnGravar = new System.Windows.Forms.Button();

                    //

                    // mainMenu1

                    //

                    this.mainMenu1.MenuItems.Add(this.menuItem1);

                    //

                    // menuItem1

                    //

                    this.menuItem1.Text = "Sair";

                    this.menuItem1.Click += new System.EventHandler(this.menuItem1_Click);

                    //

                    // dataGrid1

                    //

                    this.dataGrid1.Location = new System.Drawing.Point(8, 8);

                    this.dataGrid1.Size = new System.Drawing.Size(224, 128);

                    this.dataGrid1.Text = "dataGrid1";

                    //

                    // label1

                    //

                    this.label1.Location = new System.Drawing.Point(8, 144);

                    this.label1.Size = new System.Drawing.Size(56, 16);

                    this.label1.Text = "Nome";

                    //

                    // txtNome

                    //

                    this.txtNome.Location = new System.Drawing.Point(8, 160);

                    this.txtNome.Size = new System.Drawing.Size(224, 20);

                    this.txtNome.Text = "";

                    //

                    // txtTelefone

                    //

                    this.txtTelefone.Location = new System.Drawing.Point(8, 200);

                    this.txtTelefone.Size = new System.Drawing.Size(104, 20);

                    this.txtTelefone.Text = "";

                    //

                    // label2

                    //

                    this.label2.Location = new System.Drawing.Point(8, 184);

                    this.label2.Size = new System.Drawing.Size(56, 16);

                    this.label2.Text = "Telefone";

                    //

                    // btnNovo

                    //

                    this.btnNovo.Location = new System.Drawing.Point(120, 200);

                    this.btnNovo.Size = new System.Drawing.Size(48, 20);

                    this.btnNovo.Text = "Novo";

                    this.btnNovo.Click += new System.EventHandler(this.btnNovo_Click);

                    //

                    // btnSalvar

                    //

                    this.btnSalvar.Location = new System.Drawing.Point(8, 240);

                    this.btnSalvar.Size = new System.Drawing.Size(208, 20);

                    this.btnSalvar.Text = "Salvar XML";

                    this.btnSalvar.Click += new System.EventHandler(this.btnSalvar_Click);

                    //

                    // btnGravar

                    //

                    this.btnGravar.Location = new System.Drawing.Point(176, 200);

                    this.btnGravar.Size = new System.Drawing.Size(56, 20);

                    this.btnGravar.Text = "Gravar";

                    this.btnGravar.Click += new System.EventHandler(this.btnGravar_Click);

                    //

                    // Form1

                    //

                    this.Controls.Add(this.btnGravar);

                    this.Controls.Add(this.btnSalvar);

                    this.Controls.Add(this.btnNovo);

                    this.Controls.Add(this.txtTelefone);

                    this.Controls.Add(this.label2);

                    this.Controls.Add(this.txtNome);

                    this.Controls.Add(this.label1);

                    this.Controls.Add(this.dataGrid1);

                    this.Menu = this.mainMenu1;

                    this.Text = "Usando XML no DataSet";

                    this.Load += new System.EventHandler(this.Form1_Load);

 

             }

             #endregion

 

             static void Main()

             {

                    Application.Run(new Form1());

             }

 

             void GeraXML()

             {

                    DataTable dtAgenda = new DataTable("agenda");

                    dtAgenda.Columns.Add("Codigo", typeof(Int32));

                    dtAgenda.Columns.Add("Nome", typeof(String));

                    dtAgenda.Columns.Add("Telefone", typeof(String));

                    dsXML.Tables.Add(dtAgenda);      

                    dsXML.WriteXml(caminhoXML);

                    dsXML.WriteXmlSchema(caminhoXSD);

             }

 

             void CarregaXML()

             {

                    dsXML.ReadXmlSchema(caminhoXSD);

                    dsXML.ReadXml(caminhoXML);

                    dataGrid1.DataSource = dsXML.Tables["agenda"];

             }

 

             private void Form1_Load(object sender, System.EventArgs e)

             {

                    dsXML = new DataSet();

                    if (!File.Exists(caminhoXML))

                    {

                           GeraXML();

                    }

 

                    CarregaXML();

 

                    txtNome.DataBindings.Add("text", dsXML.Tables["agenda"], "Nome");

                    txtTelefone.DataBindings.Add("text", dsXML.Tables["agenda"], "Telefone");

             }

 

            

             private void menuItem1_Click(object sender, System.EventArgs e)

             {

                    Application.Exit();

             }

 

             private void btnSalvar_Click(object sender, System.EventArgs e)

             {

                    dsXML.WriteXml(caminhoXML);

             }

 

             private void btnNovo_Click(object sender, System.EventArgs e)

             {

                    DataRow row;

                    row = dsXML.Tables["agenda"].NewRow();

                    row["Codigo"] = dsXML.Tables["agenda"].Rows.Count;

                    dsXML.Tables["agenda"].Rows.Add(row);

                    dsXML.AcceptChanges();

             }

 

             private void btnGravar_Click(object sender, System.EventArgs e)

             {

                    dsXML.AcceptChanges();

             }

 

 

       }

}

 

O método GeraXML cria um objeto do tipo DataTable como nome de Agenda com os campos e suas definições do documento XML, adiciona está DataTable a coleção de tabelas do DataSet, escreve o documento XML e o XML Schema.

O método CarregaXML é responsável por ler o XML Schema e o documento XML no DataSet e depois ligar o DataGrid ao DataSet para exibição dos dados.

O evento Load do Form1(Form1_Load) é criada o objeto dsXML do tipo DataSet, o método GeraXML só será invocado se o documento XML não existir ou seja na primeira execução do projeto será criado o documento XML e o XML Schema, é necessário fazer referência ao namespace System.IO, é invocado o método CarregaXML independente se o documento XML existe ou não e por fim é feita a ligação dos TextBox aos campos do DataSet.

O evento clique do btnNovo(btnNovo_Click) cria um novo registro no DataTable Agenda atribuindo um valor seqüencial para o campo código o método AcceptChanges do DataSet é responsável por comitar todas as alterações feitas.

O evento clique do btnGravar(btnGravar_Click) chama o método AcceptChanges do DataSet para comitar as alterações.

O evento clique do btnSalvar(btnSalvar_Click) grava o documento XML com os dados do dsXML.

O evento clique do MenuItem(menuItem1_Click) é responsável por finalizar a aplicação.

Executando o Projeto

Compile e execute o projeto no emulador padrão, insira alguns novos registros a cada registro clique em Gravar para comitar as alterações e depois grave o documento XML, note que no diretório (\Program Files\PCDataSet\) o documento XML e o XML Schema estão gravados, reabra a aplicação e veja que os dados inseridos anteriormente foram carregados automaticamente do documento XML, como ilustra a Figura 4.

 

                                       

Figura 4. Aplicativo em execução e o documento XML e o XML Schema gravados nos diretórios das constantes.

Caso o nome do seu projeto seja diferente altere nas constantes de PCDataSet para o seu nome do projeto.

Conclusões

Vimos como é muito fácil manipular documento XML usando DataSet uma alternativa ao uso de um banco de dados SQL CE por exemplo.