Além das formas de entrada e saída vistas anteriormente, outra muito comum abrange entrada e saída de informações em sistemas por meio de arquivos XML. Este formato de arquivo guarda informações organizadas semanticamente por tags de forma hierárquica. Já que é um formato que não depende das plataformas de hardware ou de software é muito utilizado para fazer exportação e importação de dados, troca de informações entre sistemas diferentes, migração de dados entre bancos de dados, etc. Abaixo temos um exemplo do conteúdo de um arquivo do tipo XML.
<bookstore> <book> <title>The Autobiography of Benjamin Franklin</title> <author> <first-name>Benjamin</first-name> <last-name>Franklin</last-name> </author> <price>8.99</price> </book> <book> <title>The Confidence Man</title> <author> <first-name>Herman</first-name> <last-name>Melville</last-name> </author> <price>11.99</price> </book> <book> <title>The Gorgias</title> <author> <name>Plato</name> </author> <price>9.99</price> </book> </bookstore>
Nesta primeira parte vamos ler um arquivo XML e imprimí-lo no terminal. Para isto abra o Visual C#, crie um projeto vazio (File > New Project… > Empty Project) com o nome LeituraXML. No Solution Explorer clique com o botão direito do mouse no nome do projeto LeituraXML e selecione adicione um novo item (Add > New Item…). Na janela que surgir selecione o item Code File, este arquivo vai se chamar “LeituraXML.cs”. Neste arquivo, crie uma classe com de nome LeituraXML e adicione nela o método Main.
O código a seguir realiza a leitura de um arquivo .xml e imprime seu conteúdo no console. Para isto vamos utilizar objetos do tipo XmlTextReader para guardar a referência de um stream de entrada, note que desta vez o objeto é específico para trabalhar com documentos XML. Esta classe pertence ao namespace System.Xml. Logo, temos que adicionar em References a biblioteca chamada System.Xml.dll. No solution explorer vá em References, clique com o botão direito e selecione Add Reference…
Na janela que surgir busque na aba .NET a dll System.Xml e clique OK.
Nós vamos usar o método XmlTextReader.Read que pode ler vários tipos de nós, porém vamos utilizar os três mais básicos:
- Início de um elemento – Ex.: <nome>
- Texto de um elemento – Ex.: Carlos
- Fim de um elemento – Ex.: </nome>
Sabendo disto só precisamos descobrir que tipo de nó o XmlTextReader.Read leu a cada iteração do loop. Isto é possível testando a propriedade XmlTextReader.NodeType por três valores correspondentes aos três tipos de nós que estamos trabalhando.
- XmlNodeType.Element – se foi lido o início de elemento
- XmlNodeType.Text – se foi lido o texto de um elemento
- XmlNodeType.EndElement – se foi lido um fim de elemento
Nós faremos este teste usando um switch dentro do while, como implementado no código a seguir:
//LeituraXML.cs
using System.Xml;
using System.IO;
class LeituraXML
{
static void Main(string[] args)
{
//abre um stream para a leitura do arquivo xml
XmlTextReader leitor = new XmlTextReader(args[0]);
while (leitor.Read())
{
//verificacao do tipo de nó lido
switch (leitor.NodeType)
{
case XmlNodeType.Element: // The node is an element.
System.Console.Write(leitor.Name);
System.Console.Write(": ");
break;
case XmlNodeType.Text: //Display the text in each element.
System.Console.WriteLine(leitor.Value);
break;
case XmlNodeType.EndElement: //Display the end of the element.
break;
}
}
//fechamento do arquivo XML
leitor.Close();
}
}
Compilado e executado utilizando o exemplo de xml dado acima, obtivemos a saída a seguir:
O próximo passo é escrever em um arquivo .xml. Esta tarefa é um pouco mais complexa que a leitura. Antes de começar precisamos saber qual será o conteúdo do nosso domumento xml. Podemos por exemplo criar uma classe Funcionário onde cada funcionário possui três atributos: nome, cargo e email. É a partir de uma lista de funcionários que vamos construir o nosso documento.
//Funcionario.cs
public class Funcionario
{
public string nome;
public string cargo;
public string email;
}
Naturalmente o tipo de objeto que vamos utilizar para a nossa tarefa é XmlTextWriter. A primeira diferença do que nós temos visto nos códigos anteriores está na construção deste objeto, quando vamos ter que passar, além do nome do arquivo de saída, o tipo de encoding, que é UTF8.
XmlTextWriter escritor = new XmlTextWriter(args[0], System.Text.Encoding.UTF8);
Durante a escrita nós podemos determinar que o documento seja indentado automaticamente atribuindo à propriedade XmlTextWriter.Formatting o valor Formatting.Indented.
O documento deve iniciar com um cabeçalho padrão: <?xml version=”1.0″ encoding=”utf-8″ ?>. Para isto vamos utilizar o método XmlTextWriter.WriteStartDocument.
No nosso contexto precisamos criar um nó raiz com nome funcionarios que vai englobar os vários funcionários que serão armazenados no nosso documento. Exemplo:
escritor.WriteStartElement("funcionarios");
Produzindo como resultado o início de um elemento:
<funcionarios>
Para fechá-lo basta chamar WriteEndElement:
escritor.WriteEndElement();
Produzindo como resultado o fim de um elemento:
</funcionarios>
É possível também abrir e fechar uma tag já com uma string como conteúdo utilizando apenas um comando.
escritor.WriteElementString("elemento", "conteudo");
O código anterior gera a seguinte saída:
<elemento>conteudo</elemento>
Com estes métodos já podemos construir o nosso exemplo de aplicação. Para a ilustrar a utilização básica de formatos xml, o exemplo a seguir vai exportar dados de funcionários que estão armazenados em uma lista para o formato XML. Desta maneira uma outra aplicação poderia ler o arquivo XML, recuperar as informações e então manipulá-las.
//EscritaXML.cs
using System.Xml;
using System.Collections.Generic;
//classe que representa um Funcionario
class Funcionario
{
public string nome;
public string cargo;
public string email;
}
class EscritaXML
{
static void Main(string[] args)
{
//criando uma pequena lista de funcionários para ser transformada em xml
List<Funcionario> func = new List<Funcionario>()
{
new Funcionario() { nome = "Carlos", cargo = "advogado",
email = @"carlos@email.com" },
new Funcionario() { nome = "Joao", cargo = "bombeiro",
email = @"joao@gmail.com" },
new Funcionario() { nome = "Michel", cargo = "medico",
email = @"michel@gmail.com" }
};
//abrindo (ou criando) o documento XML para escrita
XmlTextWriter escritor = new XmlTextWriter(args[0],
System.Text.Encoding.UTF8);
//comando de formatacao do documento (indentacao)
escritor.Formatting = Formatting.Indented;
//iniciando o documento
escritor.WriteStartDocument();
//escrevendo o elemento raiz do documento
escritor.WriteStartElement("funcionarios");
foreach (Funcionario x in func)
{
//iniciando o elemento funcionário
escritor.WriteStartElement("funcionario");
escritor.WriteElementString("nome", x.nome);
escritor.WriteElementString("cargo", x.cargo);
escritor.WriteElementString("email", x.email);
//fechando o elemento funcionário
escritor.WriteEndElement();
}
//fechando o elemento raiz
escritor.WriteEndElement();
//fechando o documento
escritor.WriteEndDocument();
escritor.Close();
}
}
Compilando e executando o código acima obtivemos a seguinte saída no terminal:




