Boa noite!
Hoje apresento a vocês o formato de arquivo .xml (eXtensible Markup Language), o qual é muito utilizado para o armazenamento das principais configurações de software e informações diversas, desde variáveis do programa até informações sobre os diretórios de arquivos utilizados no projeto, como por exemplo, o diretório de um arquivo de imagens.
Seu emprego se deve à sua simplicidade e universalidade (possui infraestrutura única que pode ser usada por diversas linguagens de programação). É muito usada par ao compartilhamento de informações através da internet e tem forte semelhança com a estrutura da linguagem HTML.
Exemplo de arquivo .xml.
Seu conteúdo pode ser editado como um documento de texto simples, igual ao formato .html, tornando-o ainda mais interessante. Além disso, até os comentários seguem o mesmo padrão de HTML: (<!--comentário-->).
Arquivo .xml gerado pelo projeto Bizuca.
---//---
Vamos agora trabalhar em um pequeno exemplo de como implementar uma classe geradora e leitora de arquivos .xml para gerenciar as informações de nosso programa.
--- [Estrutura da Classe] ---
Os principais métodos da classe que manipulam o arquivo .xml são os seguintes:---> loadXML()
Método que verifica a existência do arquivo XML. Caso exista, lê o arquivo. Caso contrário, o cria usando valores default.Em Game.java também há invocações diretas para gerar o arquivo .xml, salvando alterações das configurações do jogo.
------> lerXml();
Faz o mapeamento das configurações descritas no arquivo .xml e as variáveis do objeto da classe Config.java. Em outras palavras, carrega as configurações do arquivo e as atribui devidamente.
------> gerarXml();Cria um documento com as informações do programa (variáveis da classe Config.java) e chama o conversor do documento para .xml. Depois de realizada a operação, chama o método para salvar o arquivo final.
---------> converter();
A partir do documento recebido como parâmetro, faz a conversão ao formato .xml.
---------> salvarArquivo();Salva o arquivo .xml gerado.
--- [Implementação] ---
Primeiramente, vamos importar as bibliotecas necessárias. Vamos usar as API's nativas do JDK para isso, de modo que não é necessário adicionar bibliotecas externas:
import org.w3c.dom.*; import org.xml.sax.*; import javax.xml.parsers.*; import javax.xml.transform.*; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.*;
Como queremos um objeto da classe de configurações global, vamos implementá-lo segundo as técnicas aprendidas no post passado. Logo em seguida, já podemos declarar as variáveis do arquivo de configurações, bem como definir sua inicialização padrão (caso não seja possível carregar o arquivo .xml):
public class Config { private static Config instance; public static Config getInstance(){ if (instance == null) instance = new Config(); return instance; } // Variáveis diversas public String title = "Web Bizuca"; public int HTela = 1280, VTela = 720; //...
---[ loadXML() ]---
Então, agora vamos criar um método intermediário entre a classe de configurações e a classe que faz uso destas configurações, que deverá ser invocado no escopo da classe que faz uso destas configurações:private static File file = new File("src\\config.xml"); public void loadXML() { try{ if (file.exists()) lerXml(); else gerarXml(); } catch(Exception e){} }
---[ gerarXML() ]---
Se o arquivo .xml não for encontrado, o procedimento é utilizar os valores padrão de variável atribuídos no próprio escopo da classe. A partir destes dados, é gerado um novo arquivo .xml atrave´s do método gerarXml(). O mesmo método é empregado pode ser empregado na classe de utilização para guardar alterações de modificação das configurações do programa. Esse método tem a seguinte estrutura:[ funcionamento ]
-> Deleta o arquivo .xml, caso ele exista-> Cria um novo documento e adiciona Elementos (Tags) a ele:
Element WindowTitle = doc.createElement("Title");
-> A cada Tag, pode ser atribuído um conteúdo interno a ele:
WindowTitle.setTextContent("Web Bizuca");
-> Cada Tag filha deve ser depois adicionada a uma Tag pai ou ao próprio documento:subTagWindowConfig.appendChild(WindowTitle);
doc.appendChild(tagConfig);
-> Depois de criado o documento, é preciso convertê-lo ao formato .xml, que é feito usando a função converter()
-> O arquivo .xml editado é salvo
[ funcionamento ]
O código exemplo ilustrativo é mostrado abaixo:
public void gerarXml() throws Exception { if (file.exists()) file.delete(); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.newDocument(); Element tagConfig = doc.createElement("Config"); Element subTagWindowConfig = doc.createElement("Config_Window"); Element WindowTitle = doc.createElement("Title"); Element WindowWidth = doc.createElement("Window_Width"); Element WindowHeigth = doc.createElement("Window_Height"); WindowTitle.setTextContent("Web Bizuca"); WindowWidth.setTextContent(""+HTela); WindowHeigth.setTextContent(""+VTela); subTagWindowConfig.appendChild(WindowTitle); subTagWindowConfig.appendChild(WindowWidth); subTagWindowConfig.appendChild(WindowHeigth); tagConfig.appendChild(subTagWindowConfig); doc.appendChild(tagConfig); String arquivo = converter(doc); salvarArquivo(arquivo); }
---[ converter() ]---
Basicamente, converte o documento que é recebido como parâmetro para o formato padrão de um arquivo .xml, cujo conteúdo é retornado em forma de string.private static String converter(Document document) throws TransformerException { Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); StreamResult result = new StreamResult(new StringWriter()); DOMSource source = new DOMSource(document); transformer.transform(source, result); String xmlString = result.getWriter().toString(); return xmlString; }
[ lerXml() ]
Abre o arquivo .xml e, a partir da identificação das Tags, faz a leitura dos dados do arquivo e atribui seus valores às variáveis da classe de configurações, como o exemplo abaixo:private static void lerXml() throws Exception, SAXException, TransformerException { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(new InputSource(file.toString())); Element raiz = doc.getDocumentElement(); NodeList endList = raiz.getElementsByTagName("Config_Window"); Element endElement = (Element) endList.item(0); instance.title = getChildTagValue(endElement, "Title"); instance.HTela = Integer.parseInt(getChildTagValue(endElement,"Window_Width")); instance.VTela = Integer.parseInt(getChildTagValue(endElement,"Window_Height")); }
Faz a busca do valor de determinada Tag do arquivo .xml, retornando o seu valor:[ getChildTagValue() ]
public static String getChildTagValue(Element elem, String tagName) throws Exception { NodeList children = elem.getElementsByTagName(tagName); String result = null; if (children == null) return result; Element child = (Element) children.item(0); if (child == null) return result; result = child.getTextContent(); return result; }
--- [Conclusão] ---
Fizemos neste post a geração e leitura manual das informações de um arquivo .xml, o que pode ser um processo um tanto penoso em um projeto grande. Poderíamos ter usado Arrays / ArrayLists para gravar estas informações, porém seria mais difícil saber a finalidade de cada uma das variáveis se não houver uma boa documentação sobre elas, de forma que por finalidades didáticas preferimos nomear uma a uma as variáveis de configuração.
Qualquer dúvida, acesse uma das referências ou consulte a classe Config.java do projeto Web Bizuca, disponibilizado no link abaixo:
https://github.com/ftuyama/Web-Bizuca
Referências:
http://pt.wikipedia.org/wiki/XML
http://www.mballem.com/post/manipulando-arquivo-xml-parte-i-api-nativa/
Nenhum comentário:
Postar um comentário