Gerando XML com vários models no Rails
Na semana passada eu escrevi um post sobre como gerar um XML a partir de um modelo no Rails, com algumas opções que facilitam a nossa vida. Mas e quando precisamos gerar um XML que não é formado só com os dados de um único modelo? Será que o to_xml resolve?
A princípio, a resposta é não. Primeiro porque uma vez que você tem uma instância de algum model (por exemplo, User.find(:first)), você não consegue adicionar a ele propriedades que não estão definidas no próprio modelo (ou através de algum método dele). Segundo que se você montar um vetor com modelos diferentes (por exemplo, User e Article), o XML será gerado usando o termo records para designar esse conjunto de objetos e record para designar cada elemento.
Isso se torna um problema quando você precisa exportar os dados do seu banco para outro sistema usando XML, como é o caso da troca de informação sobre atendimentos médicos, cujo padrão foi definido pela ANS. Esse padrão foi definido como Troca de Informações em Saúde Suplementar (TISS), e estabelece, usando um namespace próprio, como os dados devem ser formatados para que possam ser enviadas informações de faturamento, por exemplo.
Ah, sim, mas voltando à pergunta: e daí? Como eu faço isso?
Uma das inúmeras alternativas que existem é usar o Builder::XmlMarkup.
Para instalá-lo, execute:
gem install builder
e para utilizá-lo é muito simples:
xm = Builder::XmlMarkup.new(:indent => 4)
xm.instruct!
xm.html {
xm.head {
xm.title("History")
}
xm.body {
xm.comment! "HI"
xm.h1("Header")
xm.p("paragraph")
}
}
Veja que eu especifiquei que a identação do XML tem que conter 4 espaços. O código acima vai gerar o XML abaixo (HTML não deixa de ser XML!):
<?xml version="1.0" encoding="UTF-8"?>
<html>
<head>
<title>History</title>
</head>
<body>
<! -- HI -->
<h1>Header</h1>
<p>paragraph</p>
</body>
</html>
Uma particularidade do XmlMarkup que pode causar confusão no começo é que praticamente qualquer método que você tentar utilizar vai virar um atributo do xml. Ou seja, se você tentar utilizar xm.to_s no código acima, esperando que ele mostre todo o XML pra você como uma string, você pode se surpreender vendo que agora o teu XML tem mais um atributo: <to_s/>. Se você quiser que o teu objeto XmlMarkup vire uma string em outra variável, utilize o parâmetro :target do construtor. Assim, a variável que for passada como target sempre conterá uma string que é o teu XML.
Outra forma de criar atributos aninhados no XML através do XmlMarkup é usar um bloco de código, assim:
var = ""
xm = Builder::XmlMarkup.new(:target => var)
xm.tag!("html") do
xm.tag!("head") do
xm.tag!("title", "Título da página")
end
end
Que vai gerar o seguinte:
<html>
<head>
<title>Título da página</title>
</head>
</html>
Ou seja, a mesma coisa do exemplo anterior, só que feito de forma diferente. Repare que desta vez eu especifiquei o target do XmlMarkup. Dessa forma. a variável var conterá uma string que é o meu XML (e dessa forma não seremos tentados a usar xm.to_s)
E pra finalizar, aquilo que eu sempre digo: para mais detalhes, consulte a documentação
.
Poderia avaliar este artigo, por favor? |
