Leitura e Escrita de arquivos XML em C#

quarta-feira, 23 de junho de 2010 por Daniel Machado

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:

Tags: ,

Deixe um comentário