Trabalhando com XML
Transcrição
Trabalhando com XML
Trabalhando com XML RENATO CORREIA DE MATOS Para que aplicações heterogêneas possam se comunicar é necessário que haja um padrão. Uma boa escolha para a troca de mensagens seria por meio de arquivo texto, pois nesse caso o conteúdo da mensagem poderá ser entendido por todos os sistemas independente da sua plataforma. O padrão atual que vem sendo usado é o XML (Extensible Markup Language). Nesse artigo irei abordar diferentes caminhos para se trabalhar com arquivos XML, criaremos um mecanismo Parser para varrer as TAGS de um documento XML e também veremos como usar DataSets para gerenciar XML. O .NET FRAMEWORK provém classes que possibilitam navegar dentro de um documento XML e extrair suas informações. XML Document Object Model ou simplesmente XML DOM Usando XML DOM você pode carregar todo o documento XML para a memória e realizar as operações básicas como leitura e edição do conteúdo. No exemplo abaixo temos um arquivo texto que contém informações sobre uma lista de contatos, formatado dentro do padrão XML. <?xml version=’1.0’?> <contatos> <contato> <nome>Renato</nome> <telefone>2214362</telefone> <email>[email protected]</email> </contato> <contato> <nome>Fernando</nome> <telefone>30940054</telefone> <email>[email protected]</email> </contato> </contatos> No XML apresentado <CONTATOS> é o nó PAI. O nó imediatamente filho dele é <CONTATO> sem o “S”. Quando NOS encontram-se posicionados no mesmo nível como: <nome>, <telefone> e <email> dizemos que eles são irmãos. O XML DOM contém diferentes tipos de nós. Vamos descrevê-los na tabela que se encontra logo abaixo: Tipo de Nó DOCUMENT DOCUMENTTYPE ELEMENT ATTRIBUTE COMMENT TEXT Descrição É o container para todos os nós. Também é chamado de ROOT Representa o <!DOCTYPE> Os elementos ou TAGS O tipo de atributo de um elemento Uma breve descrição sobre o conteúdo Um texto para representação do nó ou atributo Existem dois caminhos para se carregar um XML para ser analisado por uma variável usando XML DOM. Podemos usar tanto o método load e especificar um arquivo XML ou então loadxml e informar todo o conteúdo como um parâmetro. Vejamos o código abaixo para melhor entendê-los: 1. Abra o Visual Studio 2005 e crie um novo projeto do tipo Windows Application de acordo com a figura abaixo: 2. Adicione um Button e um TextBox. E no evento OnClick do botão adicione o código abaixo. Mas não esqueça de antes acrescentar o namespace System.XML para poder usar a classe XmlDocument. Exemplo 1: using System.Xml; private void ButtonLoad_Click(object sender, EventArgs e) { XmlDocument doc = new XmlDocument(); doc.Load("c:\\temp\\contatos.xml"); textBox1.Text = doc.InnerText.ToString(); } No código acima, após a realização da carga do XML para a variável doc e acionarmos a propriedade InnerText o conteúdo que é apresentado dentro do TextBox não é exibido junto das TAGS XML. Somente o texto das TAGS é retornado. Agora substitua o código do evento OnClick pelo que se encontra logo abaixo. Veremos uma outra maneira de se carregar um documento XML usando o método loadxml: Exemplo 2: XmlDocument doc = new XmlDocument(); doc.LoadXml("<contatos>"+ "<contato>"+ "<nome>Renato</nome>"+ "<telefone>2214362</telefone>"+ "<email>[email protected]</email>"+ "</contato>"+ "<contato>"+ "<nome>Fernando</nome>"+ "<telefone>30940054</telefone>"+ "<email>[email protected]</email>"+ "</contato>"+ "</contatos>"); textBox1.Text = doc.InnerText.ToString(); Diferente do nosso primeiro exemplo, no código a cima passamos todo o conteúdo do XML por parâmetro para dentro do método. No exemplo a seguir ao invés de apresentar o texto do XML, vamos gerar um arquivo em disco baseado no valor de uma string xmlData que será previamente formatada. Para isso substitua o código do evento OnClick pelo que segue logo abaixo: Exemplo 3: XmlDocument doc = new XmlDocument(); String xmlData = "<contatos>"+ "<contato>"+ "<nome>Renato</nome>"+ "<telefone>2214362</telefone>"+ "<email>[email protected]</email>"+ "</contato>"+ "<contato>"+ "<nome>Fernando</nome>"+ "<telefone>30940054</telefone>"+ "<email>[email protected]</email>"+ "</contato>"+ "</contatos>"; doc.LoadXml(xmlData); doc.Save("c:\\temp\\dados.xml"); Criando um XML Parser Em nosso próximo exemplo, iremos criar um Parser, ou seja, um analisador para percorrer todo o arquivo XML e apresentar o seu conteúdo de uma maneira mais amigável. Diferente do exemplo anterior que simplesmente mostramos todo o conteúdo por meio da propriedade InnerText, vamos analisar cada elemento e apresenta-lo juntamente com o seu conteúdo. Substitua novamente o código do seu botão pelo que está sendo mostrado logo abaixo: XmlDocument doc = new XmlDocument(); doc.Load("c:\\temp\\contatos.xml"); // contador de registros lidos int i = 0; // após carregar o arquivo, vamos começar a leitura // pelo primeiro nó do vetor ChildNodes, ou seja, pelo nó <CONTATOS> // do nosso documento apresentado no começo do artigo XmlNode root = doc.ChildNodes[1]; foreach (XmlNode xmlnode in root.ChildNodes) { i++; textBox1.AppendText("Lendo nó "+i.ToString()+"-"+xmlnode.Name); textBox1.AppendText("\n"); // agora vamos pegar os NOS filhos de <CONTATO> e seus valores foreach (XmlNode texto in xmlnode.ChildNodes) { textBox1.AppendText(texto.Name+"="+texto.FirstChild.Value); textBox1.AppendText("\n"); } } Após a execução da rotina acima observe que o cnteúdo apresentado já está bem diferente do que foi visto em nosso primeiro exemplo. Isso porque fizemos uma leitura detalhada em todos os nós do nosso documento. Trabalhando com XMLReader e XMLWriter O namespace System.Xml contém duas classes abstratas XMLReader e XMLWriter que já realizam o Parser de arquivos XML quer sejam Streams ou XmlDocument. A partir delas nós poderemos herdar nossas próprias classes e então realizar nossas customizações ou então usar as classes já herdadas XmlTextReader e XmlTextWriter para o fácil acesso ao conteúdo de um documento XML. No nosso próximo exemplo criaremos uma página WEB para exibir o conteúdo de arquivos XML. Abra o Visual Studio 2005 e crie um novo projeto Web em: File à New à Web Site. Selecione o Template ASP.NET Web Site conforme figura abaixo: No evento OnLoad digite o código abaixo para carregar um arquivo XML. private void loadXML() { XmlTextReader reader = new XmlTextReader(@"c:\temp\contatos.xml"); String xmlData = ""; while (reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: xmlData += "<" + reader.Name; while (reader.MoveToNextAttribute()) xmlData += reader.Name + " = " + reader.Value; xmlData += "> <br>"; break; case XmlNodeType.Text: xmlData += reader.Value + "<br>"; break; case XmlNodeType.EndElement: xmlData += "</" + reader.Name + ">"; break; } } Response.Write(xmlData); } protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) loadXML(); } No exemplo acima, criamos um método loadXml para realizar a carga do arquivo. Usando a classe XMLTextReader conseguimos percorrer todos os nós encontrados e de acordo com tipo de nó identificado realizamos a exibição dos valores. Vejamos agora uma utilização da classe XmlTextWriter. private void saveXML() { XmlTextWriter wr = new XmlTextWriter(@"c:\temp\contatos.xml", System.Text.Encoding.UTF8); wr.Formatting = Formatting.Indented; // acrescenta a linha <?xml version?> wr.WriteStartDocument(true); // especificação do xml wr.WriteDocType("contatos", "", "", ""); wr.WriteComment("Agenda de contatos"); // criação do root e valores wr.WriteStartElement("contatos"); wr.WriteStartElement("contato"); wr.WriteElementString("nome", "Mario Andrade"); wr.WriteElementString("email", "[email protected]"); wr.WriteElementString("fone", "5555-5555"); wr.WriteEndElement(); wr.WriteEndElement(); // finaliza o documento wr.Flush(); wr.Close(); } No exemplo acima geramos um documento XML sem utilização do método Save apresentado no começo do artigo. Com alguns métodos básicos tais como: WriteStartElement e WriteElementString criamos o nosso arquivo e o deixamos formatado de acordo com a apresentação do quadro abaixo: <?xml version="1.0" encoding="utf-8" standalone="yes"?> <!DOCTYPE contatos PUBLIC "" ""[]> <!--Agenda de contatos--> <contatos> <contato> <nome>Mario Andrade</nome> <email>[email protected]</email> <fone>5555-5555</fone> </contato> </contatos> Em nosso último exemplo, usaremos a classe DataSet para ler e gerar arquivos XML a partir de uma base de dados. Usando o banco de dados Northwind que acompanha o SQL Server, faremos um SELECT na tabela PRODUCTS e em seguida iremos gerar o nosso arquivo XML a partir do DataSet que já estará populado. private void saveXMLDB() { SqlConnection conn = new SqlConnection("user id=sa;pwd=;initial catalog=Northwind;data source=localhost"); conn.Open(); SqlDataAdapter da = new SqlDataAdapter("select ProductId, ProductName from products"); DataSet ds = new DataSet(); da.Fill(ds, "Temp"); ds.WriteXml(@"c:\temp\produtos.xml", XmlWriteMode.IgnoreSchema); } Observe que no exemplo acima usamos o método Fill da classe SqlDataAdapater para popular o nosso DataSet. Usando o método WriteXml salvamos todo o conteúdo do DataSet para uma arquivo XML. Esse método recebe no seu segundo parâmetro um valor do tipo XmlWriteMode que poderá ser: DiffGram: Esse formato de arquivo é usado implicitamente para troca de dados com um serviço do tipo WebService. Pois os valores são serializados para depois serem transferidos, o que gerante um bom desempenho na transferência. IgnoreSchema: Esse é o valor padrão. Neste caso apenas o conteúdo, ou seja, os dados sem as informações do Schema como tipos de dados, tamanhos e nome de campos serão transferidas. WriteSchema: Tanto os dados como a estrutra será gerada dentro do arquivo XML. Agora que geramos o arquivo em disco, vamos fazer a leitura do conteúdo salvo para dentro do DataSet. Acompanhem o exemplo abaixo e vejam como é simples usar um DataSet para capturar e apresentar o conteúdo de um arquivo XML. Adicione um DataGrid a sua página principal e implemente o código que se encontra logo abaixo: private void loadXMLDB() { DataSet ds = new DataSet("Temp"); ds.ReadXml(@"c:\temp\produtos.xml"); GridView1.DataSource = ds; GridView1.DataBind(); } protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) loadXMLDB(); } Após a execução do método loadXMLDB sua página deverá estar de acordo com a figura abaixo: Conclusão Nesse artigo podemos entender porque o XML é o preferido padrão de comunicação entre as aplicações. Com ele você não precisa ficar lendo trechos de um arquivo de texto para extrair informações como acontece diariamente na troca de mensagens entre os arquivos de Remessa e Retorno de Bancos. Um outro motivo é a clareza com o que as informações nos são apresentadas. De cara você detecta logo do que se trata o arquivo sem a necessidade de um documento para detalhar cada conjunto de dados. Vimos que XML DOM é uma boa escolha para representar um arquivo XML na memória. Com essa classe podemos ler e gerar documentos XML. Um outro detalhe importante do artigo foi verificar-mos que dento do namespace System.XML podemos contar com a ajuda das classes XmlTextReader e XmlTextWrite para realizar a análise desses arquivos. E por último vimos como é simples utilizar DataSet para exibição e geração de arquivos. Renato Matos é Consultor Borland em SP. Trabalha com Delphi desde a sua primeira versão. Atualmente participa em projetos com as Ferramentas de ALM Borland e Desenvlvimento Code Gear. Você pode entrar em contato pelo email [email protected]