um parser xml simples e robusto vitor pastor baracho

25
um parser XML simples e robusto Vitor Pastor Baracho

Upload: internet

Post on 17-Apr-2015

140 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Um parser XML simples e robusto Vitor Pastor Baracho

um parser XML simples e robusto

Vitor Pastor Baracho

Page 2: Um parser XML simples e robusto Vitor Pastor Baracho

Em resumo, o TinyXML analisa uma sequência de entrada (no caso um documento XML) e determina uma estrutura independente de plataforma ou linguagem: um Modelo de Objeto de Documentos (DOM), que permite trabalhar com os elementos de modo altamente dinâmico e independente.

Isto significa que o TinyXML armazena a informação do documento XML em objetos C++ que podem ser manipulados livremente.

Page 3: Um parser XML simples e robusto Vitor Pastor Baracho

Ao analisar o problema da CEMIG, percebemos que era necessário um mecanismo capaz de retirar os dados da entrada XML e transferi-los para a estrutura de dados da OGDF.

A TinyXML mostrou ser a biblioteca ideal para a tarefa, visto que ela é extremamente compacta, elaborada para um rápido e fácil aprendizado, e robusta (o código foi muito testado e é bastante maduro e estável). Além disto, ela é distribuída sob a licença Zlib e pode ser usada para fins de código aberto ou comerciais.

Page 4: Um parser XML simples e robusto Vitor Pastor Baracho

A TinyXML pode ser compilada para utilizar ou não a STL.

TinyXML é compatível com UTF-8, de modo a permitir que arquivos XML sejam manipulados em qualquer linguagem.

Page 5: Um parser XML simples e robusto Vitor Pastor Baracho

A TinyXML reconhece os seguintes caracteres especiais pré-definidos:

&amp; & &lt; < &gt; > &quot; " &apos; '

Eles são reconhecidos quando o documento XML é lido.

Page 6: Um parser XML simples e robusto Vitor Pastor Baracho

A saída pode ser gerada de várias maneiras diferentes, que possuem vantagens e limitações:

1- Print( FILE* ). Saída para um std-C stream, que incluem todos os arquivos de C assim como stdout.

2- Operador <<. Saída para um C++ stream.3- Objeto TiXmlPrinter. Saída para um std::string ou

buffer de memória. É uma classe da TinyXML que permite diversas funções de formatação e é útil quando se deseja uma saída para memória.

Page 7: Um parser XML simples e robusto Vitor Pastor Baracho

Caso TIXML_USE_STL esteja ativado, a biblioteca é compatível com os operadores de fluxo em C++ (>>, <<) além dos C(FILE*) streams.

A seguir, algumas diferenças que devem ser consideradas:

Page 8: Um parser XML simples e robusto Vitor Pastor Baracho

Em C:Entrada:Baseada em FILE*;Métodos Parse() e LoadFile();Saída:Baseada em FILE*;Métodos Print() e SaveFile();

São métodos rápidos e tolerantes a erros no documento XML. A saída gerada é de leitura facilitada para humanos. Devem ser usados quando não se precisar dos streams de C++.

Page 9: Um parser XML simples e robusto Vitor Pastor Baracho

Em C++:Entrada:Baseada em std::istream;Operador >>;Saída:Baseada em std::ostream;Operador <<;

São métodos mais lentos, porém úteis para transmissões na rede. Não são tolerantes a erros, como por exemplo dois elementos root em um documento XML.

Page 10: Um parser XML simples e robusto Vitor Pastor Baracho

A TinyXML é compatível com a remoção de espaços duplicados, e com a manutenção destes.

Por exemplo:Caso a função estática global

TiXmlBase::SetCondeseWhiteSpace(bool) seja setada, a biblioteca irá condensar todos os espaços em branco em um só, caso contrário não. Ela é setada como default.

Page 11: Um parser XML simples e robusto Vitor Pastor Baracho

Handles permitem acesso direto a elementos do documento XML, de modo a permitir a verificação de código (retornos nulos de funções) e ainda permitir que o código continue limpo.

Para mais informações, vale a pena consultar a classe TiXmlHandle, na documentação da biblioteca.

Page 12: Um parser XML simples e robusto Vitor Pastor Baracho

A TinyXML permite que nós e atributos sejam rastreados no documento fonte.

Para isto, são utilizados os métodos TiXmlBase::Row() e TiXmlBase::Column().

As tabulações corretas podem ser configuradas utilizando o método TiXmlDocument::SetTabSize().

Page 13: Um parser XML simples e robusto Vitor Pastor Baracho

Um Makefile em Linux e uma solução para o Visual C++ estão disponíveis no site, e podem ser compilados e executados.

Para utilizar a biblioteca em uma aplicação, como no problema da CEMIG, basta adicionar os arquivos tinyxml.cpp, tinyxml.h, tinyxmlerror.cpp, tinyxmlparser.cpp, tinystr.cpp, e tinystr.h para o projeto ou makefile.

Page 14: Um parser XML simples e robusto Vitor Pastor Baracho

O exemplo disponível na documentação, utiliza o seguinte documento XML como entrada:

<?xml version="1.0" standalone=no> <!-- Our to do list data --> <ToDo> <Item priority="1"> Go to the <bold>Toy store!</bold></Item> <Item priority="2"> Do bills</Item> </ToDo>

Page 15: Um parser XML simples e robusto Vitor Pastor Baracho

Para ler este exemplo, de um arquivo (digamos exemplo.xml), cria-se um documento e carrega o arquivo nele:

TiXmlDocument doc( “exemplo.xml" );doc.LoadFile();

Com isto, o documento já está carregado na estrutura, e pronto para ser manipulado.

Page 16: Um parser XML simples e robusto Vitor Pastor Baracho

Vamos dar uma olhada nas linhas do documento, e como elas se relacionam com a estrutura:

<?xml version="1.0" standalone=no>

A primeira linha do documento é uma declaração e se transforma em um objeto da classe TiXmlDeclaration. Ele vai ser o primeiro filho do nó documento. Esta é a única tag diretiva/especial cujo parse é feito pela biblioteca. Normalmente as tags são armazenadas em um objeto TiXmlUnknown.

Page 17: Um parser XML simples e robusto Vitor Pastor Baracho

A próxima linha é:

<!-- Our to do list data -->

Este comentário irá se tornar um objeto da classe TiXmlComment.

Page 18: Um parser XML simples e robusto Vitor Pastor Baracho

Continuando...

<ToDo>

Esta tag define um objeto da classe TiXmlElement. Este especificamente não contém atributos, porém contém outros dois elementos:

<Item priority="1">

Cria outro elemento TiXmlElement que é um filho do elemento ToDo. Este elemento possui um atributo com o nome (name) “priority” e o valor (value) “1”.

Page 19: Um parser XML simples e robusto Vitor Pastor Baracho

Go to the

Um TiXmlText. Este objeto é um nó folha (leaf node) e não pode conter outros elementos. Ele é filho do TiXmlElement “Item”.

<bold>

Outro TiXmlElement, também é filho do TiXmlElement “Item”.

E assim sucessivamente...

Page 20: Um parser XML simples e robusto Vitor Pastor Baracho

Olhando a árvore final dos objetos instanciados, obtém-se:

|TiXmlDocument "demo.xml" |TiXmlDeclaration "version='1.0'" "standalone=no" |TiXmlComment "Our to do list data" |TiXmlElement "ToDo"

|TiXmlElement "Item" Attributes: “priority” = “1”|TiXmlText "Go to the" |TiXmlElement "bold"

|TiXmlText "Toy store!" |TiXmlElement "Item" Attributes: “priority”= “2”

|TiXmlText "Do bills"

Page 21: Um parser XML simples e robusto Vitor Pastor Baracho

Mais um Exemplo

Dado um arquivo XML, será mostrado como extrair informação do mesmo para ser utilizado em um aplicação.

Estas informações são extraídas utilizando principalmente a classe TiXmlHandle.

O exemplo foi adaptado do Tutorial fornecido pelos autores da TinyXML

Page 22: Um parser XML simples e robusto Vitor Pastor Baracho
Page 23: Um parser XML simples e robusto Vitor Pastor Baracho

TiXmlDocument doc( "entrada_teste.xml" );doc.LoadFile();

TiXmlHandle hDoc(&doc);TiXmlElement* pElem;TiXmlHandle hRoot(0);

cout << "Teste! Leitura do arquivo XML!" << endl << endl;pElem = hDoc.FirstChildElement().Element();hRoot = TiXmlHandle(pElem);AppName = pElem->Value();

cout << "Primeira TAG do arquivo XML: " << AppName << endl;

Page 24: Um parser XML simples e robusto Vitor Pastor Baracho

cout << "Mostrando todas as TAGs filhas de \"GOPACApp\":" << endl;pElem = hRoot.FirstChildElement().Element();for ( pElem; pElem; pElem = pElem->NextSiblingElement() )

cout << "\t- " << pElem->Value() << endl;

cout << endl << "Mostrando todas as mensagens:\n";pElem = hRoot.FirstChild("Messages").FirstChildElement().Element();for ( pElem; pElem; pElem = pElem->NextSiblingElement() )

cout << "[ " << pElem->Value() << " ]: " << pElem->GetText() << endl;

Page 25: Um parser XML simples e robusto Vitor Pastor Baracho

cout << endl << "Informacoes sobre FRAMES:\n";pElem = hRoot.FirstChild("Windows").FirstChildElement().Element();for ( pElem; pElem; pElem = pElem->NextSiblingElement() ){

cout << pElem->Value() << ": " << pElem->Attribute("name") << endl;cout << "\t x: " << pElem->Attribute("x") << endl;cout << "\t y: " << pElem->Attribute("y") << endl;cout << "\t w: " << pElem->Attribute("w") << endl;cout << "\t h: " << pElem->Attribute("h") << endl << endl;

}