Software Design

Design de software em C, C++, Java, etc…

Wrapper LibXML2 para C++

Precisei utilizar a libxml2 em um projeto recentemente e como ainda não tinha utilizado essa biblioteca precisei estudar sua documentação. Ao ler a documentação achei ela bastante complicada de utilizar. A complicação vem do fato de a API dela ser feita em C e por isso não conta com alguns recursos que poderiam facilitar. Cheguei a ler um pouco sobre a libxml++ mas também não gostei da sua sintaxe, além de trazer mais uma dependência desnecessária ( glibmm ). Como um dos requisitos do projeto que estou trabalhando é utilizar a libxml2 por ser um projeto legado, resolvi então criar um wrapper para facilitar o uso dessa biblioteca.

A idéia desse wrapper é tornar a utilização da libxml2 o mais simples possível, por isso o design não foi pensando em performance – não que a performance seja tão ruim, mas possui um overhead de memória pelo fato de o parser fazer cópias os nós em memória. Mas não é nada muito preocupante ( à não ser que seu arquivo xml possua centenas de megabytes ).

Bom, vamos ao código. O projeto do wrapper está hospedado no github ( https://github.com/filipenf/libxml-cpp-wrapper ). Para utilizá-lo você precisa da libxml2 pré-instalada com os headers disponíveis, além do cmake para gerar os makefiles. Após baixar os arquivos do repositório, crie um diretório para os arquivos de build e digite o seguinte:

$ git clone https://github.com/filipenf/libxml-cpp-wrapper.git
$ mkdir build && cd build
$ cmake ../libxml-cpp-wrapper/
$ make && sudo make install

A biblioteca será compilada e instalada e os headers serão copiados para o diretório /usr/local/include.

Agora é só desenvolver utilizando o nosso wrapper, normalmente você não precisará incluir os headers da libxml2 em seus fontes, bastará utilizar os headers do wrapper.

#include <iostream>
#include <string>
#include <XMLReader.h>

using namespace std;

const string xml_string =
"<CustomerList><Customer><Name>John Smith</Name><ContactInfo>\
<Address>22 Acacia Avenue</Address><OfficePhone>123456\
</OfficePhone></ContactInfo></Customer></CustomerList>";

int main(int argc, char* argv[]) {
    list<XMLNode> nodes;
    XMLReader<XMLMemoryParser> reader(xml_string);
    reader.parse(nodes);
    XMLNode &node = *nodes.begin();
    string phone = node["Customer"]["ContactInfo"]["OfficePhone"].text;
    string addr = node["Customer"]["ContactInfo"]["Address"].text;
    cout << "Phone: " << phone << endl << "Address: " << addr << endl;
}    

Compile o código com o seguinte comando:

$ g++ xml.cpp -I/usr/local/include -I/usr/local/include/libxml2 -l xmlcppwrapper -lxml2
$ ./a.out 
Phone: 123456
Address: 22 Acacia Avenue

Pronto, utilizamos o nosso parser para ler os nós do conteúdo XML que estava em memória. Como você pode perceber pelo código, o wrapper utiliza sobrecarga de operadores para acesso aos nós-filhos, facilitando muito a busca por itens, principalmente quando não é necessário iteração, mas quando for necessário é possível utilizar os métodos firstChild e lastChild para obter iteradores e poder percorrer um determinado nó.

Outra facilidade deste wrapper é não ter a necessidade de ficar checando se um determinado nó existe ( por exemplo se o xml não tivesse um nó OfficePhone abaixo de ContactInfo, receberíamos um nó vazio mas nenhum erro/exception é lançada ).

Concluindo, acho que o wrapper facilita bastante a vida de quem utiliza a libxml2 em códigos C++. Em um próximo post estarei comentando sobre como utilizar a classe XMLBuilder para montar o conteúdo XML à partir de objetos XMLNode.

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

Informação

Publicado às outubro 9, 2012 por em C++ e marcado , , , , .
%d blogueiros gostam disto: