And After - Design e Tecnologia por Sua Conta!
OD

Interpretando XML com Jquery

Média

Por Guilherme Serrano em Internet, Programação,

Exemplo de interpretação de XML utilizando a biblioteca Javascript jQuery. Neste caso o XML lido é um feed das buscas do Twitter.

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:

  1. Economia de banda no seu servidor
  2. Maior chance de usar o cache do usuário, diminuindo o tempo e carregamento
  3.  
<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&amp;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&amp;page=2&amp;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&#233;ns pra ti, #odesenvolvedor com um crescimento de 50% na visita&#231;&#227;o no &#250;tlimo m&#234;s! :D</title>

    <content type="html">&lt;a href="http://twitter.com/chrisloki"&gt;@chrisloki&lt;/a&gt; parab&#233;ns pra ti, &lt;a href="/search?q=%23odesenvolvedor"&gt;#odesenvolvedor&lt;/a&gt; com um crescimento de 50% na visita&#231;&#227;o no &#250;tlimo m&#234;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&#233;ns o/ uhu!</title>

    <content type="html">&lt;a href="http://twitter.com/gserrano"&gt;@&lt;b&gt;gserrano&lt;/b&gt;&lt;/a&gt; parab&#233;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 &#233; fascinante, animais disfar&#231;ados de folha. ah, sapecas! http://tinyurl.com/5q8c88</title>

    <content type="html">a natureza &#233; fascinante, animais disfar&#231;ados de folha. ah, sapecas! &lt;a href="http://tinyurl.com/5q8c88"&gt;http://tinyurl.com/5q8c88&lt;/a&gt;</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 &#250;ltimo m&#234;s. (olhando as novidades do google analyctics).</title>

    <content type="html">um culto ao ego, &lt;a href="/search?q=%23andafter"&gt;#andafter&lt;/a&gt; teve um crescimento de 15% nas visitas no &#250;ltimo m&#234;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&#234; foi um dos pioneiros a falar das buscas no iSofa.tv. Por isso te adicionei. Obrigado. Abra&#231;os.</title>

    <content type="html">&lt;a href="http://twitter.com/gserrano"&gt;@&lt;b&gt;gserrano&lt;/b&gt;&lt;/a&gt; Voc&#234; foi um dos pioneiros a falar das buscas no iSofa.tv. Por isso te adicionei. Obrigado. Abra&#231;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&#234; est&#225; curtindo. Tem mais de 300 canais aguardando pra entrar no menu novo. Avise qqc.</title>

    <content type="html">&lt;a href="http://twitter.com/gserrano"&gt;@&lt;b&gt;gserrano&lt;/b&gt;&lt;/a&gt; Obrigado, cara, muito legal saber que voc&#234; est&#225; 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">&lt;a href="http://twitter.com/gserrano"&gt;@&lt;b&gt;gserrano&lt;/b&gt;&lt;/a&gt; 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. &#233; que simplesmente n&#227;o rolou produ&#231;&#227;o, vamos ver se a noite melhora. :D</title>

    <content type="html">&lt;a href="http://twitter.com/oPadreVoador"&gt;@oPadreVoador&lt;/a&gt; que assim seja! mas eu nem deveria descansar. &#233; que simplesmente n&#227;o rolou produ&#231;&#227;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, &#243;tima alternativa para minhas madrugadas. :D</title>

    <content type="html">&lt;a href="http://twitter.com/bpinaud"&gt;@bpinaud&lt;/a&gt; bem vindo! e parabens pelo isofa, &#243;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&#233;m tenta promover uma coisa pr&#243;pria sem dizer que tem liga&#231;&#227;o com aquilo. S&#243; passa desconfian&#231;a.</title>

    <content type="html">Acho mto ruim quando algu&#233;m tenta promover uma coisa pr&#243;pria sem dizer que tem liga&#231;&#227;o com aquilo. S&#243; passa desconfian&#231;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&#225; que amanh&#227; eu descanso? *-*</title>

    <content type="html">&lt;a href="http://twitter.com/gserrano"&gt;@&lt;b&gt;gserrano&lt;/b&gt;&lt;/a&gt; hoje foi meu dia de correria, ser&#225; que amanh&#227; 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&#237; pra compensar hj eu n&#227;o fiz NADA.</title>

    <content type="html">Ontem o dia foi uma correria do capeta, a&#237; pra compensar hj eu n&#227;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? &lt;a href="http://tinyurl.com/5obmlo"&gt;http://tinyurl.com/5obmlo&lt;/a&gt;</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&#227;o, mas vou fazer" &#233; o que diferencia homens de meninos. gogo! :D</title>

    <content type="html">&lt;a href="http://twitter.com/chrisloki"&gt;@chrisloki&lt;/a&gt; &amp;quot;eu sei que n&#227;o, mas vou fazer&amp;quot; &#233; 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. :)

Veja o exemplo funcionando.