Estudando jQuery para o desenvolvimento de novas ferramentas para o And After (a nova Vitrine Buscapé) resolvi publicar um artigo exemplificando como ler XML com jQuery.
Primeiro devo deixar claro que meu relacionamento com Javascript é bem tímido, o pouco que sei são aprendizados recentes mas o jQuery tem ajudado muito por facilitar bastantes as coisas. Sei que o Chris vai dizer que Prototype apresenta mais vantagens, mas testei rapidamente as duas bibliotecas sem saber quase nada de Javascript e a que teve mais efetividade no desenvolvimento foi jQuery, que optei por estudar.
"Instalando" o jQuery
O primeiro passo para utilizar a biblioteca é fazer com o que o usuário carregue ela, não baixe ela no seu servidor, o Google Ajax Libraries faz isso e traz duas vantagens principais:
- Economia de banda no seu servidor
- Maior chance de usar o cache do usuário, diminuindo o tempo e carregamento
<script src="http://www.google.com/jsapi"></script> <script type="text/javascript"> //1 - carrega bibliotecas prototype e scriptaculous google.load("jquery", "1.2.6"); </script>
Biblioteca colocada na página, podemos agora passar para o próximo passo.
XML
Aqui está a estrutura do XML que utilizei para o exemplo, utilizei este feed, que exibe os resultados da busca no Twitter pelo meu username (@gserrano), mas poderia ser resultados do Flickr, do Google, do feed do seu blog ou de um relatório de um aplicativo web.
<?xml version="1.0" encoding="UTF-8"?> <feed xmlns:google="http://base.google.com/ns/1.0" xml:lang="en-US" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns="http://www.w3.org/2005/Atom" xmlns:twitter="http://api.twitter.com/"> <id>tag:search.twitter.com,2005:search/gserrano</id> <link type="text/html" rel="alternate" href="http://search.twitter.com/search?q=gserrano"/> <link type="application/atom+xml" rel="self" href="http://search.twitter.com/search.atom?q=gserrano"/> <title>gserrano - Twitter Search</title> <link type="application/opensearchdescription+xml" rel="search" href="http://search.twitter.com/opensearch.xml"/> <link type="application/atom+xml" rel="refresh" href="http://search.twitter.com/search.atom?q=gserrano&since_id=1011974184"/> <updated>2008-11-18T23:30:00Z</updated> <openSearch:itemsPerPage>15</openSearch:itemsPerPage> <link type="application/atom+xml" rel="next" href="http://search.twitter.com/search.atom?max_id=1011974184&page=2&q=gserrano"/> <entry> <id>tag:search.twitter.com,2005:1011974184</id> <published>2008-11-18T23:30:00Z</published> <link type="text/html" rel="alternate" href="http://twitter.com/gserrano/statuses/1011974184"/> <title>@chrisloki parabéns pra ti, #odesenvolvedor com um crescimento de 50% na visitação no útlimo mês! :D</title> <content type="html"><a href="http://twitter.com/chrisloki">@chrisloki</a> parabéns pra ti, <a href="/search?q=%23odesenvolvedor">#odesenvolvedor</a> com um crescimento de 50% na visitação no útlimo mês! :D</content> <updated>2008-11-18T23:30:00Z</updated> <link type="image/png" rel="image" href="http://s3.amazonaws.com/twitter_production/profile_images/62939563/gserrano2_normal.jpg"/> <link type="application/atom+xml" rel="thread" href="http://search.twitter.com/search/thread/1011974184.atom"/> <author> <name>gserrano (Guilherme Serrano)</name> <uri>http://twitter.com/gserrano</uri> </author> </entry> <entry> <id>tag:search.twitter.com,2005:1011941353</id> <published>2008-11-18T23:06:02Z</published> <link type="text/html" rel="alternate" href="http://twitter.com/chrisloki/statuses/1011941353"/> <title>@gserrano parabéns o/ uhu!</title> <content type="html"><a href="http://twitter.com/gserrano">@<b>gserrano</b></a> parabéns o/ uhu!</content> <updated>2008-11-18T23:06:02Z</updated> <link type="image/png" rel="image" href="http://s3.amazonaws.com/twitter_production/profile_images/61066338/ble_normal.jpg"/> <link type="application/atom+xml" rel="thread" href="http://search.twitter.com/search/thread/1011941353.atom"/> <author> <name>chrisloki (Chris Benseler)</name> <uri>http://twitter.com/chrisloki</uri> </author> </entry> <entry> <id>tag:search.twitter.com,2005:1011934314</id> <published>2008-11-18T23:01:16Z</published> <link type="text/html" rel="alternate" href="http://twitter.com/gserrano/statuses/1011934314"/> <title>a natureza é fascinante, animais disfarçados de folha. ah, sapecas! http://tinyurl.com/5q8c88</title> <content type="html">a natureza é fascinante, animais disfarçados de folha. ah, sapecas! <a href="http://tinyurl.com/5q8c88">http://tinyurl.com/5q8c88</a></content> <updated>2008-11-18T23:01:16Z</updated> <link type="image/png" rel="image" href="http://s3.amazonaws.com/twitter_production/profile_images/62939563/gserrano2_normal.jpg"/> <author> <name>gserrano (Guilherme Serrano)</name> <uri>http://twitter.com/gserrano</uri> </author> </entry> <entry> <id>tag:search.twitter.com,2005:1011925155</id> <published>2008-11-18T22:54:46Z</published> <link type="text/html" rel="alternate" href="http://twitter.com/gserrano/statuses/1011925155"/> <title>um culto ao ego, #andafter teve um crescimento de 15% nas visitas no último mês. (olhando as novidades do google analyctics).</title> <content type="html">um culto ao ego, <a href="/search?q=%23andafter">#andafter</a> teve um crescimento de 15% nas visitas no último mês. (olhando as novidades do google analyctics).</content> <updated>2008-11-18T22:54:46Z</updated> <link type="image/png" rel="image" href="http://s3.amazonaws.com/twitter_production/profile_images/62939563/gserrano2_normal.jpg"/> <author> <name>gserrano (Guilherme Serrano)</name> <uri>http://twitter.com/gserrano</uri> </author> </entry> <entry> <id>tag:search.twitter.com,2005:1011912798</id> <published>2008-11-18T22:46:14Z</published> <link type="text/html" rel="alternate" href="http://twitter.com/bpinaud/statuses/1011912798"/> <title>@gserrano Você foi um dos pioneiros a falar das buscas no iSofa.tv. Por isso te adicionei. Obrigado. Abraços.</title> <content type="html"><a href="http://twitter.com/gserrano">@<b>gserrano</b></a> Você foi um dos pioneiros a falar das buscas no iSofa.tv. Por isso te adicionei. Obrigado. Abraços.</content> <updated>2008-11-18T22:46:14Z</updated> <link type="image/png" rel="image" href="http://s3.amazonaws.com/twitter_production/profile_images/52836833/BPeoLeao_normal.JPG"/> <link type="application/atom+xml" rel="thread" href="http://search.twitter.com/search/thread/1011912798.atom"/> <author> <name>bpinaud (Bruno Pinaud)</name> <uri>http://twitter.com/bpinaud</uri> </author> </entry> <entry> <id>tag:search.twitter.com,2005:1011871230</id> <published>2008-11-18T22:17:19Z</published> <link type="text/html" rel="alternate" href="http://twitter.com/bpinaud/statuses/1011871230"/> <title>@gserrano Obrigado, cara, muito legal saber que você está curtindo. Tem mais de 300 canais aguardando pra entrar no menu novo. Avise qqc.</title> <content type="html"><a href="http://twitter.com/gserrano">@<b>gserrano</b></a> Obrigado, cara, muito legal saber que você está curtindo. Tem mais de 300 canais aguardando pra entrar no menu novo. Avise qqc.</content> <updated>2008-11-18T22:17:19Z</updated> <link type="image/png" rel="image" href="http://s3.amazonaws.com/twitter_production/profile_images/52836833/BPeoLeao_normal.JPG"/> <link type="application/atom+xml" rel="thread" href="http://search.twitter.com/search/thread/1011871230.atom"/> <author> <name>bpinaud (Bruno Pinaud)</name> <uri>http://twitter.com/bpinaud</uri> </author> </entry> <entry> <id>tag:search.twitter.com,2005:1011868941</id> <published>2008-11-18T22:15:50Z</published> <link type="text/html" rel="alternate" href="http://twitter.com/oPadreVoador/statuses/1011868941"/> <title>@gserrano hahaha, tomara o/ que melhore ai e que eu descanse aqui ;D</title> <content type="html"><a href="http://twitter.com/gserrano">@<b>gserrano</b></a> hahaha, tomara o/ que melhore ai e que eu descanse aqui ;D</content> <updated>2008-11-18T22:15:50Z</updated> <link type="image/png" rel="image" href="http://s3.amazonaws.com/twitter_production/profile_images/60831933/opvlogovp0_normal.png"/> <link type="application/atom+xml" rel="thread" href="http://search.twitter.com/search/thread/1011868941.atom"/> <author> <name>oPadreVoador (oPadreVoador)</name> <uri>http://twitter.com/oPadreVoador</uri> </author> </entry> <entry> <id>tag:search.twitter.com,2005:1011861566</id> <published>2008-11-18T22:10:40Z</published> <link type="text/html" rel="alternate" href="http://twitter.com/gserrano/statuses/1011861566"/> <title>que acharam do photobucket do wall-e? eu adoro os backrounds do photobucket.</title> <content type="html">que acharam do photobucket do wall-e? eu adoro os backrounds do photobucket.</content> <updated>2008-11-18T22:10:40Z</updated> <link type="image/png" rel="image" href="http://s3.amazonaws.com/twitter_production/profile_images/62939563/gserrano2_normal.jpg"/> <author> <name>gserrano (Guilherme Serrano)</name> <uri>http://twitter.com/gserrano</uri> </author> </entry> <entry> <id>tag:search.twitter.com,2005:1011857210</id> <published>2008-11-18T22:07:39Z</published> <link type="text/html" rel="alternate" href="http://twitter.com/gserrano/statuses/1011857210"/> <title>@oPadreVoador que assim seja! mas eu nem deveria descansar. é que simplesmente não rolou produção, vamos ver se a noite melhora. :D</title> <content type="html"><a href="http://twitter.com/oPadreVoador">@oPadreVoador</a> que assim seja! mas eu nem deveria descansar. é que simplesmente não rolou produção, vamos ver se a noite melhora. :D</content> <updated>2008-11-18T22:07:39Z</updated> <link type="image/png" rel="image" href="http://s3.amazonaws.com/twitter_production/profile_images/62939563/gserrano2_normal.jpg"/> <link type="application/atom+xml" rel="thread" href="http://search.twitter.com/search/thread/1011857210.atom"/> <author> <name>gserrano (Guilherme Serrano)</name> <uri>http://twitter.com/gserrano</uri> </author> </entry> <entry> <id>tag:search.twitter.com,2005:1011847664</id> <published>2008-11-18T22:01:28Z</published> <link type="text/html" rel="alternate" href="http://twitter.com/gserrano/statuses/1011847664"/> <title>@bpinaud bem vindo! e parabens pelo isofa, ótima alternativa para minhas madrugadas. :D</title> <content type="html"><a href="http://twitter.com/bpinaud">@bpinaud</a> bem vindo! e parabens pelo isofa, ótima alternativa para minhas madrugadas. :D</content> <updated>2008-11-18T22:01:28Z</updated> <link type="image/png" rel="image" href="http://s3.amazonaws.com/twitter_production/profile_images/62939563/gserrano2_normal.jpg"/> <link type="application/atom+xml" rel="thread" href="http://search.twitter.com/search/thread/1011847664.atom"/> <author> <name>gserrano (Guilherme Serrano)</name> <uri>http://twitter.com/gserrano</uri> </author> </entry> <entry> <id>tag:search.twitter.com,2005:1011843370</id> <published>2008-11-18T21:58:46Z</published> <link type="text/html" rel="alternate" href="http://twitter.com/gserrano/statuses/1011843370"/> <title>Acho mto ruim quando alguém tenta promover uma coisa própria sem dizer que tem ligação com aquilo. Só passa desconfiança.</title> <content type="html">Acho mto ruim quando alguém tenta promover uma coisa própria sem dizer que tem ligação com aquilo. Só passa desconfiança.</content> <updated>2008-11-18T21:58:46Z</updated> <link type="image/png" rel="image" href="http://s3.amazonaws.com/twitter_production/profile_images/62939563/gserrano2_normal.jpg"/> <author> <name>gserrano (Guilherme Serrano)</name> <uri>http://twitter.com/gserrano</uri> </author> </entry> <entry> <id>tag:search.twitter.com,2005:1011820041</id> <published>2008-11-18T21:43:32Z</published> <link type="text/html" rel="alternate" href="http://twitter.com/oPadreVoador/statuses/1011820041"/> <title>@gserrano hoje foi meu dia de correria, será que amanhã eu descanso? *-*</title> <content type="html"><a href="http://twitter.com/gserrano">@<b>gserrano</b></a> hoje foi meu dia de correria, será que amanhã eu descanso? *-*</content> <updated>2008-11-18T21:43:32Z</updated> <link type="image/png" rel="image" href="http://s3.amazonaws.com/twitter_production/profile_images/60831933/opvlogovp0_normal.png"/> <link type="application/atom+xml" rel="thread" href="http://search.twitter.com/search/thread/1011820041.atom"/> <author> <name>oPadreVoador (oPadreVoador)</name> <uri>http://twitter.com/oPadreVoador</uri> </author> </entry> <entry> <id>tag:search.twitter.com,2005:1011815993</id> <published>2008-11-18T21:40:49Z</published> <link type="text/html" rel="alternate" href="http://twitter.com/gserrano/statuses/1011815993"/> <title>Ontem o dia foi uma correria do capeta, aí pra compensar hj eu não fiz NADA.</title> <content type="html">Ontem o dia foi uma correria do capeta, aí pra compensar hj eu não fiz NADA.</content> <updated>2008-11-18T21:40:49Z</updated> <link type="image/png" rel="image" href="http://s3.amazonaws.com/twitter_production/profile_images/62939563/gserrano2_normal.jpg"/> <author> <name>gserrano (Guilherme Serrano)</name> <uri>http://twitter.com/gserrano</uri> </author> </entry> <entry> <id>tag:search.twitter.com,2005:1011776936</id> <published>2008-11-18T21:15:30Z</published> <link type="text/html" rel="alternate" href="http://twitter.com/gserrano/statuses/1011776936"/> <title>que tal servir aperitivo num ralo pra banheiro? http://tinyurl.com/5obmlo</title> <content type="html">que tal servir aperitivo num ralo pra banheiro? <a href="http://tinyurl.com/5obmlo">http://tinyurl.com/5obmlo</a></content> <updated>2008-11-18T21:15:30Z</updated> <link type="image/png" rel="image" href="http://s3.amazonaws.com/twitter_production/profile_images/62939563/gserrano2_normal.jpg"/> <author> <name>gserrano (Guilherme Serrano)</name> <uri>http://twitter.com/gserrano</uri> </author> </entry> <entry> <id>tag:search.twitter.com,2005:1011521172</id> <published>2008-11-18T18:32:52Z</published> <link type="text/html" rel="alternate" href="http://twitter.com/gserrano/statuses/1011521172"/> <title>@chrisloki "eu sei que não, mas vou fazer" é o que diferencia homens de meninos. gogo! :D</title> <content type="html"><a href="http://twitter.com/chrisloki">@chrisloki</a> &quot;eu sei que não, mas vou fazer&quot; é o que diferencia homens de meninos. gogo! :D</content> <updated>2008-11-18T18:32:52Z</updated> <link type="image/png" rel="image" href="http://s3.amazonaws.com/twitter_production/profile_images/62939563/gserrano2_normal.jpg"/> <link type="application/atom+xml" rel="thread" href="http://search.twitter.com/search/thread/1011521172.atom"/> <author> <name>gserrano (Guilherme Serrano)</name> <uri>http://twitter.com/gserrano</uri> </author> </entry> </feed>
Interpretar XML com jQuery
Aqui está o código que ao carregar a página identifica qual XML será lido, busca pelos dados "entry" no XML e gera um loop entre eles, exibindo a mensagem que está no XML.
<script type="text/javascript"> $(function(){ $("#tweets").fadeOut("fast"); $.ajax({ type: "GET", url: "search.xml", dataType: "xml", success: function(xml) { $(xml).find("entry").each(function(){ var link = $(this).find("link").attr("href"); var texto = $(this).find("content").text(); $("<li></li>") .html(texto + " <a href=´" + link + "´>Ver tweet</a>") .appendTo("#tweets"); }); //close each( $("#tweets").fadeIn("slow"); } }); //close $.ajax( }); </script>
Neste caso utilizei a requesição utilizando a função ".ajax" do jQuery, em meus testes não consegui fazer retornar direto da busca, portanto seria necessário utilizar programação server-side como ASP ou PHP para gerar o XML para o Javascript. Não é a melhor solução se você precisa ler XML externo. Uma forma melhor de fazer isto é utilizar seu servidor como Proxy através do Isapi Rewrite (para quem utiliza IIS) e acredito que deve ser possível com htaccess. Se alguém tem alguma dica melhor, estou aqui mais para aprender do que para ensinar, comenta aí! 🙂
Talvez uma estudada em XML-RPC resolva este problema para ler o XML externo, se não me engano eu já fiz isso só com jQuery, mas acho que estava utilizando JSON e não XML como resposta.
A função .ajax carrega o arquivo search.xml (o xml que utilizei no exemplo) e chama a função para a leitura. Chamei um loop para cada "entry" encontrado no meu XML, portanto "entry" é cada linha que eu gostaria de ler (no caso, cada tweet retornado pela busca).
Busquei apenas duas variáveis, o link para o tweet original:
var link = $(this).find("link").attr("href");
Que no XML está como o atributo href, na linha abaixo:
<link type="text/html" rel="alternate" href="http://twitter.com/gserrano/statuses/1011776936"/>
E recuperei também o texto do tweet, que são as duas únicas variáveis que utilizei para o exemplo. Dentro do loop eu criei elementos de lista <li></li>, onde adicionei as variáveis e no final utilizei o .appendTo para inserir cada elemento da lista dentro do elemento com ID tweets que deve estar no HTML.
A função fade é opcional, utilizei apenas porque sou designer para suavizar a visualização no carregamento da lista.
HTML
Como explicado acima, depois de montar a lista o script procura o elemento com o id tweets, portanto a única coisa necessária no HTML do documento é uma lista <ul> ou <ol> com o id correto.
<ol id="tweets"></ol>
É isso, qualquer sugestão ou dúvida comente, como eu disse: estou muito mais apto a aprender do que a ensinar por aqui, mas espero ter ajudado. 🙂