Trabalhando com XML em Rust: visão geral das principais bibliotecas
O XML continua sendo um formato relevante para arquivos de configuração, troca de dados em sistemas legados e armazenamento de informações estruturadas. No ecossistema Rust, existem várias bibliotecas maduras para trabalhar com XML, cada uma voltada para cenários específicos: desde parsing de streaming de alto desempenho até desserialização conveniente em estruturas estritamente tipadas. Neste artigo, vamos analisar três bibliotecas principais: quick-xml, roxmltree e serde_xml_rs, além de fornecer exemplos práticos de uso.
Biblioteca quick-xml: parsing de streaming rápido
quick-xml é uma das bibliotecas mais rápidas para trabalhar com XML em Rust. Ela é projetada para ter sobrecarga mínima e baixo consumo de memória. O princípio básico de funcionamento é o parsing de streaming. Você lê o XML sequencialmente, processando eventos: tags de abertura e fechamento, texto, comentários.
Essa abordagem é ideal para processar arquivos grandes (centenas de megabytes), onde o modelo DOM (carregar todo o documento na memória) não é viável. A biblioteca suporta tanto leitura quanto escrita de XML.
Exemplo: lendo uma configuração com quick-xml
Suponha que temos um arquivo XML simples config.xml:
<config> <app name="my_app"> <port>8080</port> <host>localhost</host> </app></config>Parsing usando quick-xml e sua API de alto nível Reader:
use quick_xml::Reader;use quick_xml::events::Event;
fn main() -> Result<(), Box<dyn std::error::Error>> { let xml = r#" <config> <app name="my_app"> <port>8080</port> <host>localhost</host> </app> </config> "#;
let mut reader = Reader::from_str(xml); let mut txt = Vec::new(); let mut in_port = false;
loop { match reader.read_event() { Ok(Event::Start(ref e)) => { if e.name().as_ref() == b"port" { in_port = true; } } Ok(Event::Text(ref e)) => { if in_port { txt.push(e.unescape()?.to_string()); in_port = false; } } Ok(Event::Eof) => break, Err(e) => panic!("Error at position {}: {:?}", reader.buffer_position(), e), _ => () } } println!("Port value: {}", txt[0]); Ok(())}Como você pode ver, o código é imperativo e requer gerenciamento manual de estado, mas oferece controle total sobre o processo de parsing.
Biblioteca roxmltree: trabalhando com árvore DOM
Se você prefere trabalhar com XML como uma árvore de objetos (DOM), o roxmltree é uma excelente escolha. Ela carrega todo o documento na memória e fornece métodos convenientes para navegação: busca por consultas semelhantes a XPath, travessia de descendentes, obtenção de atributos.
A biblioteca não suporta serialização (escrita de XML), mas para leitura e análise é muito prática. Uma vantagem importante é a verificação rigorosa de namespaces.
Exemplo: buscando elementos com roxmltree
use roxmltree::Document;
fn main() -> Result<(), Box<dyn std::error::Error>> { let xml = r#" <catalog> <book id="1"> <title>Rust in Action</title> <author>Tim McNamara</author> </book> <book id="2"> <title>Programming Rust</title> <author>Jim Blandy</author> </book> </catalog> "#;
let doc = Document::parse(x Também na biblioteca
Registro em Kotlin: visão geral das melhores bibliotecas e soluções
Aprendizado de Máquina em Kotlin: visão geral das bibliotecas KMath, Smile, KotlinDL e DeepLearning4J
Trabalho com imagens: resize, crop em TypeScript