tadarank afiliados

08 dezembro, 2006

Trabalhar com XML usando JavaScript

Olá pessoal,

Hoje vou mostrar como trabalhar com XML usando apenas JavaScript (através de DOM).
Agente vê muito tutorial de XML com PHP, ASP, Java, etc, porém quase nenhum sobre JavaSript.

Ao final deste tutorial, você saberá manipular os dados de seu XML pra fazer um menu por exemplo, ou uma tabela, ou uma lista, puxar RSS, etc.

Um lembrete antes de iniciar: diferente das linguagens server-side (php, asp, etc), por motivo de segurança, o navegador não permite que você carregue qualquer arquivo que esteja fora de seu domínio, ou seja, nem adianta tentar carregar XML's ou RSS's de outros sites.

Editado em 19/12/06: Olha só outra forma interessante que eu achei no site da IBM (via MDC)

Postado também no fórum iEvolution.

Chega de papo, bora lá.

1. Fazendo um XML pro teste

(Se você já tem algum arquivo xml pode pular esta etapa)
Abra seu bloco de notas e coloque o seguinte conteúdo:

<?xml version="1.0" ?>
<pessoa>
   <identificacao id="1">
    <nome>Joao</nome>
    <email>joao@mail.com</email>
   </identificacao>
   <identificacao id="2">
    <nome familia="ze" data="2">Maria</nome>
    <email>maria@mail.com
    </email>
   </identificacao>
</pessoa>

Salve este arquivo com o nome de nomes.xml, por exemplo. Na mesma pasta deste arquivo xml, iremos criar nosso HTML que irá carregá-lo.

2) Carregando o XML

Os navegadores carregam um arquivo xml de formas diferentes. O IE usa ActiveX. Para o Firefox e Opera, iremos usar o XMLHttpRequest (o mesmo que se usa em ajax).

O código que irá retornar um objeto xml para os três navegadores citados é:

function xmlMicoxLoader(url){
  //by Micox: micoxjcg@yahoo.com.br.
    if(window.XMLHttpRequest){
        var Loader = new XMLHttpRequest();
        Loader.open("GET", url ,false);
        Loader.send(null);
        return Loader.responseXML;
    }else if(window.ActiveXObject){
        var Loader = new ActiveXObject("Msxml2.DOMDocument.3.0");
        Loader.async = false;
        Loader.load(url);
        return Loader;
    }
}

Perceba que tivemos que deixar o carregamento síncrono para que ao chegar na linha do "return" o carregamento já ter sido concluído.
Se você não sabe o que é modo síncrono ou assíncrono, no modo síncrono o script aguarda o carregamento antes de executar a próxima instrução. No modo assíncrono, o carregamento é feito em segundo plano e a execução das linhas continua indepentende de já ter chegado algum dado pelo open.
Para ler mais sobre estes modos (e suas consequências) veja esta parte do tutorial de ajax do Elcio do Tableless.com.br.

Se quiser mais informações sobre o responseXML, dê uma lida neste texto do Newton (blog Viche): a propriedade responseXML.

Pronto. Agora que agente já tem o objeto XML pra ser trabalhado, mãos à obra com o DOM.

3) Manipulando o XML

XML pode ser manipulado como se fosse um esquema de árvore através das rotinas do DOM, ou seja, pra trabalhar com o XML nós apenas manipularemos propriedades como childNodes, nodeType, nodeValue, firstChild e outras expressões bem comuns pra quem já mexeu com XML ou Javascript.

Na rotina que eu coloco abaixo, apenas faço um laço for que percorre todos os filhos do objeto XML retornado pela função xmlMicoxLoader.
A cada filho percorrido, eu pego o valor dele através de nodeValue, e os atributos através do array attributes[]. O nome dos elementos pode ser recuperado através de nodeName. Se determinado nó tem outros filhos, eu percorro estes filhos também e faço o mesmo. Bah, vá estudar DOM hehehe

Uma observação: o IE ignora os espaços em branco e não os interpreta como filhos. Eu acho isso bom. Porém o FF e o Opera, seguem os padrões e interpretam estes espaços em branco e Enter's como se fossem um elemento do tipo #text. Daí precisamos filtrar estes elementos testando o nodeType (elementos tem nodeType=1, textos tem nodeType=3).

Este exemplo apenas printa na tela o esquema XML feião mesmo. Mas já dá uma base pra você entender e trabalhar com o XML. Leia e entenda, isto é uma ordem:

function xmlMicoxArvore(xmlNode,identacao){
  //by Micox: micoxjcg@yahoo.com.br
    var arvoreTxt=""; //esta var armazenara o conteudo
    for(var i=0;i<xmlNode.childNodes.length;i++){//percorrendo os filhos do nó
  if(xmlNode.childNodes[i].nodeType == 1){//ignorar espaços em branco
   //pegando o nome do nó
   arvoreTxt = arvoreTxt + identacao + xmlNode.childNodes[i].nodeName + ": "
   if(xmlNode.childNodes[i].childNodes.length==0){
    //se não tiver filhos eu já pego o nodevalue
    arvoreTxt = arvoreTxt + xmlNode.childNodes[i].nodeValue 
    for(var z=0;z<xmlNode.childNodes[i].attributes.length;z++){
     var atrib = xmlNode.childNodes[i].attributes[z];
     arvoreTxt = arvoreTxt + " (" + atrib.nodeName + " = " + atrib.nodeValue + ")";
    }
    arvoreTxt = arvoreTxt + "<br />\n";
   }else if(xmlNode.childNodes[i].childNodes.length>0){
    //se tiver filhos eu tenho que pegar o valor pegando o valor do primeiro filho
    arvoreTxt = arvoreTxt + xmlNode.childNodes[i].firstChild.nodeValue;
    for(var z=0;z<xmlNode.childNodes[i].attributes.length;z++){
     var atrib = xmlNode.childNodes[i].attributes[z];
     arvoreTxt = arvoreTxt + " (" + atrib.nodeName + " = " + atrib.nodeValue + ")";
    }
    //recursividade para carregas os filhos dos filhos
    arvoreTxt = arvoreTxt + "<br />\n" + xmlMicoxArvore(xmlNode.childNodes[i],identacao + "> > ");
   }
      }
    }
    return arvoreTxt;
}

Agora é só chamar as funções:

xml = xmlMicoxLoader("nomes.xml"); //carrega o xml
document.write(xmlMicoxArvore(xml,"")); //printa a árvore na tela 

4) Carregando um RSS

Bom, o exemplo anterior não é muito útil não né? Serve só pra você aprender.
Vamo mostrar um exemplo mais útil: uma função que carrega um RSS de seu próprio site.

function xmlMicoxRSS(xmlNode){
 //by Micox: http://elmicox.blogspot.com
 var retorno = "";
 var objNodeList = xmlNode.getElementsByTagName("item")
 for(var i=0;i<objNodeList.length;i++){
  var strTitulo = ""
  var strURL = ""
  var strDescr = ""
  var objNode = objNodeList[i];
  if(objNode.nodeType == 1){//ignorar espaços em branco
   for(var j=0;j<objNode.childNodes.length;j++){
    var objNode2 = objNode.childNodes[j];
    if(objNode2.nodeType == 1){//ignorar espaços em branco
     switch (objNode2.nodeName) {
      case "title": 
       //alert(objNode.childNodes[j].firstChild.nodevalue);
       strTitulo = objNode2.firstChild.nodeValue; 
       break;
      case "link": 
       strURL = objNode2.firstChild.nodeValue; 
       break;
      case "description": 
       strDescr = objNode2.firstChild.nodeValue; 
       break;
     }
    }
   }
   retorno += " <li><a href='" + strURL + "'>" + strTitulo + "</a><br />" + strDescr + "</li>\n";
  }
 }
 retorno = "<ul>\n" + retorno + "</ul>";
 return retorno;
}

Agora é só jogar o resultado na sua div:

xml = xmlMicoxLoader("rss.xml"); //carrega o xml
document.getElementById(div_alvo).innerHTML = xmlMicoxRSS(xml); //lista o rss

Editado 12/12/06: O Bernardo Rufino fez outro ótimo exemplo de como se trabalhar com XML e Javascript: Criando Gráficos Dinamicamente com Ajax e XML

5) Conclusão

Pronto. Agora acho que você já tem uma base para trabalhar com XML no JavaScript da mesma forma que faz com outras linguagens.
Pra ficar bão mermo, repito, estude DOM, nem venha me fazer perguntas básicas sobre isso. :-)
Dúvidas ou se tiver algum bug aí é só me falar.

Ó, tô desestimulado de ficar escrevendo estes tutoriais gigantescos, postando notícias no blog, etc. Ninguém comenta nessa bagaça. Então comenta aí caramba.

Té a próxima.

Gostou da dica acima? Então clica nos botões de compartilhamento abaixo e me ajude a dica a subir no Google.

53 comentários:

  1. Hahaha vou comentar nessa 'bagaça'!
    Mto bom o tutorial, gostei mesmo.
    Seu blog é show de bola, tomara que não perca o formato.

    Abraços
    PPlanel

    ResponderExcluir
  2. hahaha, valeu por comentar a bagaça.

    Agora quanto ao formato, to pensando em dar uma mudada nesse visual tosco que eu fiz. Vou mudar pra algo mais padrão.

    Aceito sugestões pessoal hehe.

    ResponderExcluir
  3. Valew!! pela explicação muito boa, ja estou formatando algumas coisas!

    Abraços

    ResponderExcluir
  4. Micox, boa tarde!

    É que estou meio sem tempo prá comentar. Entretanto, tenho acompanhado algumas das suas produções em vários sites. Tem ajudado muitíssimo. Quando eu tiver formado um conhecimento mais sólido pretendo compartilhar isso com vocês. Tenho apanhado muito, por causa dessa falta de padronização dos navegadores. Um dia eu chego lá!

    Sucesso, continue!

    Vicente Domingos

    ResponderExcluir
  5. Esse é o El "Grand" Micox que eu conheço...
    Showzão de bola esse tuto, cara. Pedra preciosa mesmo!
    Um abração aê

    ResponderExcluir
  6. show micão... não sabia que dava pra fazer isso...

    ResponderExcluir
  7. Muito bom, Micox! Ótimo tutorial!

    ResponderExcluir
  8. Viche! já recebeste oito comentários (incluindo este). Muito bom o teu tuto. Parabéns!

    E obrigado pela referência ao meu post e ao blog.

    ResponderExcluir
  9. Ótimo artigo, continue escrevendo!

    ResponderExcluir
  10. Pessoal, visitem o site do William Grasel (acima) e se surpeendam com a qualidade da simplicidade.

    ResponderExcluir
  11. Muito bom Micox... Espero estar mais familiarizado com seu conteúdo em breve.

    Seu blog é indispensável.

    Abraço.

    ResponderExcluir
  12. Relaxa cara, coloca um bom CD de METAL e continue escrevendo pois você ajuda a muitos....

    hacker by linux.

    Daniel

    ResponderExcluir
  13. ta comentado.
    eu vi umas solucoes flash-xml parecidas. a sintaxe actionscript e javascript sao muito semelhantes.
    quando usar um ou outro ?

    ResponderExcluir
  14. Sim, bic. A sintaxe dos dois é bem parecida mesmo pois são ambas baseadas no ECMAScript.

    Você deve usar o actionScript quando quiser puxar o XML através de uma aplicação flash
    e o Javascript quando for uma aplicação que suporte javascript (como uma página em um navegador de internet).

    té mais :)

    ResponderExcluir
  15. Muito boa a explicação.. resolveu boa parte dos meus problemas aheuhae :)

    Agora, se puderes me ajudar, teria como eu alterar os valores dos nós e jogar o xml alterado para a session?

    Obrigada :)

    ResponderExcluir
  16. @Lara

    Uma forma é você jogar o conteúdo do xml em um textarea e submeter para a sua linguagem server-side.

    Outra forma possível é essa aqui que desenvolvemos no fórum.

    ResponderExcluir
  17. Muito bom, estou comentando só por que você esta demotivado, nao desmovita nao. Gosto do seus trabalhos.

    Beijinho.

    ResponderExcluir
  18. PQ quando se fala de Xml ninguém ensina como fazer uma SELECT dos dados como se fosse mysql, pq só ensinam a ler um arquivo inteiro?? to começando a odiar xml, pq como pegar uma var da url e escolher qual dado eu quero da merda do banco de dados xml e exibir, pq é tão dificil alguém falr sobre isso??? acho que é impossível!!!!!!!!

    ResponderExcluir
  19. Cara ta bom msm seu TUTORIAL.... tiro minhas duvidas.....valeu msm!!!!!!

    ResponderExcluir
  20. cara, estou procurando a 2 madrugadas algo como isso, muito obrigado.

    ResponderExcluir
  21. Bem legal a matéria. Dá pra ter uma visão bem geral.

    ResponderExcluir
  22. Obrigado pela informação, está sendo de grande valia durante meus estudos!

    ResponderExcluir
  23. É, muito bacaninha, compreendi o código e talz, porém não consegui visualizar o mesmo, santa ignorancia da minha parte....

    ResponderExcluir
  24. mto bom o artigo, e gostei da menção sobre acessar xml em outro dominio.

    Mas eh justamente isso q quero.. JS acessando outro dominio. Tem como? Imagino q sua resposta eh nao...
    mas entao.. como funcionam os widgets para blogs??? eles sao js embutidos no site, q acessam dados em outro dominio...

    :(

    ResponderExcluir
  25. Exato Anderson, não é possível.
    Estes widgets que você vê não é js acessando outro domínio, mas sim js acessando uma página no mesmo domínio, esta sim, por sua vez, acessa os dados do outro domínio.
    Veja sobre o ACD (ajax cross domain): http://www.ajax-cross-domain.com/

    ResponderExcluir
  26. Cara, parabéns pelo tópico!!!Me ajudou bastante e olha q é um tópico de 2006!!!

    ResponderExcluir
  27. Ow Micox,

    Diz ai entao, voce tem ideia de como funciona os js do Google ? voce pode incluir o google no site e obter dados dele. Sabe como a gente pode implementar algo parecido ?

    Vlw.. abraço

    ResponderExcluir
  28. Opa,
    cara, por motivos de segurança, javascript não tem poder pra acessar páginas de outros domínios que não o seu. Ou seja: no momento não dá.

    ResponderExcluir
  29. Cara,

    Como você faz para exibir os códigos java script coloridos dessa forma? Existe algum recurso que faça isso automáticamente.

    Eduardo Monteiro
    edmonteiro.info@gmail.com

    ResponderExcluir
  30. Opa, é com o google prettify: http://code.google.com/p/google-code-prettify/

    ResponderExcluir
  31. Excelente tutorial. muito bom, isso vai tirar duvidas de muitos.

    ResponderExcluir
  32. Esse DOM é um belo lixo, tô louco pra ver a hora em que acabar com isso e os navegadores começarem a dar suporte ao E4X.

    ResponderExcluir
  33. Cara, eu sei que fica na mesmice, mas é só reflexo do reconhecimento do seu trabalho, muito bom esse seu tuto, me ajudou bastente, e pelo visto, não só eu.Fiz uma consulta de CEP, estou nos últimos ajustes, procurei em muitos lugares algo do tipo e não achei então fiz na mão mas na parte de retornar os dados sem dar o refresh na página, seu tutorial me ajudou bastante.Quando acabar posto em algum lugar pra quem quiser aprender ou utilizar.
    Parabéns mais uma vez

    ResponderExcluir
  34. Rodrigo Xavier27 abril, 2009 15:35

    Micox, boa tarde.

    Cara, gostei bastante deste tutorial, muito bom mesmo.
    Estou com uma dúvida.
    Preciso ler uma variável xml e não um arquivo.
    Desta maneira que está no tutorial ele não consegue carregar como um xml.
    Pode me dar uma dica?
    Meu e-mail é rsx.rodrigo@gmail.com

    ResponderExcluir
  35. Valeu cara, bom trabalho. Tentar estudar mais aqui ;p

    ResponderExcluir
  36. E como ler um xml de uma url, exemplo: http://www.site.com.br/rss.xml

    ResponderExcluir
  37. É um pouquinzinho mais complicado pois envolve ferramentas externas tipo o yahoo pipes e Json.

    Mas em breve faço uma postagem sobre isso explicando, juro.

    ResponderExcluir
  38. muito boa a iniciativa... não desanime. é sempre muito bom poder contar com o apoio dos nossos amigos programadores ;)

    valeu ai t++


    thiago@estudioclick.com.br

    ResponderExcluir
  39. bacana o tutorial
    deu pra dar uma clareada geral.
    100% ainda não testei mas aposto
    que irá funcionar.

    ResponderExcluir
  40. Filipe Acácio ( Fortaleza - Ce )30 dezembro, 2009 10:56

    Ótimo Tutorial!!!
    Simples e direto.
    Muito bem explicado, parabéns!
    OBS: se o arquivo XML tiver texto com acento da erro no I.E
    mais uma vez parabéns!!!

    ResponderExcluir
  41. E ai Micox!

    Cara quase 4 anos depois e o seu blog ainda bomba com boas informações.
    Hehehehehe, dá vontade de virar blogueiro!
    hehehehehehehe..

    Seguinte, tem como receber uma string xml e recuperar os valores das tags?

    Att.
    Jesus

    ResponderExcluir
  42. hehehe

    Sim, é só pegar os nodeValue's delas.

    tá explicado acima nos exemplos :)

    ResponderExcluir
  43. Valeu cara, mt bom mesmo seu trabalho ficou excelente!

    ResponderExcluir
  44. ótimo POST continue postando! Apesar do POST ser antigo, anos depois ainda continua ajudando muita gente. Parabéns!

    ResponderExcluir
  45. Seu post é ótimo!

    Estou com um problema em colocar o xml do analytics para visualisar em php.

    Aqui o script que estou tentando:

    load('https://www.google.com/analytics/reporting/keywords?id=43640102&pdr=20110321-20110420&cmp=average&trows=10&gdfmt=nth_day#lts=1303417887454');
    $dom->save('Analytics.xml');
    ?>

    Valeu pela força!

    ResponderExcluir
  46. Marta,
    Vi q vc tá tentando pegar um relatório do google analytics.
    Antes disso vc tem que responder duas perguntas:
    1) Essa url é de um xml válido?
    2) Você fez login via php antes de tentar pegar este relatório?

    ResponderExcluir
  47. Cara, muito obrigado. Ajudo muito, abraços felicidades.. Um dia eu chego nesse nivel de conhecimento. huahuahu

    ResponderExcluir
  48. AMIGO EU QUERO FAZER UM UPLOAD DE UM ARQUIVO XML E MOSTRAR NA PAGINA DO MEU SITE O CONTEUDO DO XML VC PODERIA DIZER COMO SE FAZ?
    EMAIL EDVALDO_VALENCA@HOTMAIL.COM

    ResponderExcluir
  49. Então vamo la:
    eu tenho uma "xml" do seguinte formato...



    2008


    Almério Nunes
    cursos



    Como eu configuro o java pra mostrar isso no iphone e como eu faço pra indexar cada ID.
    Eu teria que criar um link pra cada ID () e fazer um menu com a lista de cada ID que representa um artigo diferente.
    O XML que me refiro (com algumas diferenças) esta em:

    http://www.psrb.com.br/spa/XML/SPAdC_artigos.xml
    webmaster@psrb.com.br

    ResponderExcluir
  50. nossa..
    muito bom..

    continue assim...

    ResponderExcluir
  51. Muito bom ...

    Seus tutoriais são mutio bom ...

    Abraços

    ResponderExcluir

Resultado! Concursos