Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Andrey Knupp Vital

DOMDocument - XML { PHP } , Parte - 1

Recommended Posts

Olá gente !, percebo que muita gente tem dificuldades em trabalhar com XML ou ate mesmo ler feeds RSS de algum site

enfim.. pretendo explicar nessa parte da Matéria, um pouco sobre Document Object Model ou DOM

porém não e tão dificil quanto parece, ou pode ate ser dependendo do que você deseje fazer, não vamos passar os carros na frente dos bois

pois no PHP, a biblioteca DOM tem uma grande herança relacionada ao assunto, e pretendo explicar definitivamente algumas partes dela .. :P

então, um Preview dos itens eu vou falar, e algumas referencias ..

 

 

Manual de DOMDocument :seta: http://php.net/manual/en/book.dom.php

 

Classes que serão usadas ao longo da
Matéria(s)

 

E então, essas são as classes que iremos utilizar ..

Então pra começar, vamos manipular um XML Basico, apenas gravando algumas informaçoes

e eu explicarei alguns dos metodos utilizados para isso ..

 

Vamos imaginar um album de fotos de usuários

aí, vem uma grande questão, você que trabalha com um banco muito grande, e pretende fazer

uma coisa simples, como ler um album de fotografias enviadas por um usuario ?

Ok, a tabela seria simples, ia compor poucos campos, mais podemos gravar isso em um XML

pode ate parecer dificil, seria escrever mais codigo .. mais esse e o tipo de situação não so pra fotos

como pra coisas que você pode não achar necessário armazenar em uma Base de dados ..

então vamos lá, a curto prazo, vamos pensar no seguinte heredoc ..

 

$XML = <<<XML
      <?xml version="1.0" encoding="utf-8"?>
      <albums>
          <album usuario="0669">
               <capa src="meuPrimeiroAlbum.jpg" />
               <foto id="1" classificacao="5" src="umaFoto1.jpg" />
               <foto id="2" classificacao="5" src="umaFoto2.jpg" />
               <foto id="3" classificacao="4" src="umaFoto3.jpg" />
               <foto id="4" classificacao="2" src="umaFoto4.jpg" />
               <foto id="5" classificacao="1" src="umaFoto5.jpg" />
          </album>
      </albums>
XML;

 

Nos temos aqui uma variavel $XML com a string de uma estrutura XML

então, vemos o elemento pai 'albums' é seu filho 'album' ..

que é pai de qualquer elemento que esteje dentro dele

então pra cada um dos elementos dados os seguintes attributos

 

 Elemento Pai => album ( pertence ao usuario de id [0669] ) 
 A capa do album, com seu attributo SRC que seria o PATH da imagem que foi enviada pelo usuario é definida como capa de seu album
 #Então cada foto ( elemento, nó [foto] ) , tem seus attributos {
      id => id da foto 
      classificacao => qual o nível de classificação que o usuário classfica tal imagem
      src => path da foto enviada pelo usuário
 }

Trabalharemos nessa String então ..

Após a String ser carregada com successo pelo metodo 'loadXML', podemos trabalhar nela...

<?php
   $DOMDocument = new DOMDocument( '1.0', 'utf-8' ); // Fazemnos uma nova instancia de DOMDocument, com uma versão 1.0, e codificação utf-8
   $DOMDocument->formatOutput = true; // Seta a propidade de DOMDocument 'formatOutput' como true, para uma boa identação no xml após mesclado
   /*
    * Propidade 'preserveWhiteSpace' o default é como true, mais em 'false' não irá preservar espaços em branco redundantes
    */
   $DOMDocument->preserveWhiteSpace = false;  
   // então finalmente carrego a string do XML .. 
   $DOMDocument->loadXML( $XML );
?>

 

Ok, agora dando mais atividade nessa matéria, vamos criar é ler alguns elementos

dessa string, Obs: o loadXML, carrega String, caso deseje seguir os exemplos com um arquivo XML

pode trocar o loadXML pra 'load'

 

:seta: DOMDocument - load

 

   $Albums = $DOMDocument->getElementsByTagName( 'album' )->item(0);
   $FotoNode = $DOMDocument->createElement( 'foto' );
   $Albums->appendChild( $FotoNode );
   echo $DOMDocument->saveXML();

 

Entendendo o codigo acima, a variavel $Albums, vai retornar o objeto de DOMElement

Então, oque temos que fazer e anexar o novo elemento nessa estrutura, agora o porque de item(0) ?

Pra podermos avançar o ponteiro para os filhos desse elemento, onde queremos anexar o novo elemento

mais ele na verdade não é usado exatamente pra isto, mais sim pra informar a posição de um índice ..

e tem sua propidade readOnly ( length ), que retorna a quantidade de itens daquele elemento ..

por exemplo ..

   $Albums = $DOMDocument->getElementsByTagName( 'foto' );
   for( $i = 0; $i < $Albums->length; ++$i ){
        echo $i, '<br />';
   }

o Loop for, não é necessário para isto, apenas foi um exemplo de imprimir cada valor de $i, para cada elemento encontrado

o Output seria:

0 <br />

1 <br />

2 <br />

3 <br />

4 <br />

Começando de Zero, certamente temos 5 Elementos com o nome 'foto' ..

Então se fizermos

  $Albums = $DOMDocument->getElementsByTagName( 'album' );
  echo $Albums->length;

Iria retornar 1, pois so existe um elemento com o nome de sua tag 'album'

Mais so daí, já da pra ter uma noçao, de como seria o output do XML

se eu pretendo inserir um elemento 'foto', onde nos retorna um índice 1 em $Albums, fica mais claro

Pois foi encontrado um lugar onde anexar esse elemento, o codigo seria:

 

<?php
   $Albums = $DOMDocument->getElementsByTagName( 'album' )->item(0);
   $FotoNode = $DOMDocument->createElement( 'foto' );
   $Albums->appendChild( $FotoNode );
   echo $DOMDocument->saveXML();
?>

 

o Output do XML

 

<?xml version="1.0" encoding="utf-8"?> 
<albums> 
 <album usuario="0669"> 
   <capa src="meuPrimeiroAlbum.jpg"/> 
   <foto id="1" classificacao="5" src="umaFoto1.jpg"/> 
   <foto id="2" classificacao="5" src="umaFoto2.jpg"/> 
   <foto id="3" classificacao="4" src="umaFoto3.jpg"/> 
   <foto id="4" classificacao="2" src="umaFoto4.jpg"/> 
   <foto id="5" classificacao="1" src="umaFoto5.jpg"/> 
   <foto/> 
 </album> 
</albums> 

Mais devemos notar uma coisa, estamos anexando um elemento fora de padrão no XML

percebam que não coloquei os attributos necessários para seguir o padrão desse elemento

então, vamos fazer direito !

<?php
   $Albums = $DOMDocument->getElementsByTagName( 'album' )->item(0);
   $FotoNode = $DOMDocument->createElement( 'foto' );
   $FotoNode->setAttribute( 'id', 6 );
   $FotoNode->setAttribute( 'classificacao', 2 );
   $FotoNode->setAttribute( 'src', 'umaFoto6.jpg' );
   $Albums->appendChild( $FotoNode );
   echo $DOMDocument->saveXML();
?>

Na mesma instancia de DOMElement, já podemos usar o metodo setAttribute

para setar os attributos pro elemento criado antes mesmo de anexa-lo no XML.

a saída do XML sería

<?xml version="1.0" encoding="utf-8"?> 
<albums> 
 <album usuario="0669"> 
   <capa src="meuPrimeiroAlbum.jpg"/> 
   <foto id="1" classificacao="5" src="umaFoto1.jpg"/> 
   <foto id="2" classificacao="5" src="umaFoto2.jpg"/> 
   <foto id="3" classificacao="4" src="umaFoto3.jpg"/> 
   <foto id="4" classificacao="2" src="umaFoto4.jpg"/> 
   <foto id="5" classificacao="1" src="umaFoto5.jpg"/> 
   <foto id="6" classificacao="2" src="umaFoto6.jpg"/> 
 </album> 
</albums> 

Ok !!, agora está no padrão .. já que nos falamos da parte de anexar elementos no XML

creio que todo mundo tenha entendido ;P, mais bola pra frente, vamos ler esse XML aí ..

 

<?php
  foreach( $DOMDocument->getElementsByTagName( 'album' ) as $Nodes ){
            foreach( $Nodes->childNodes as $Node ){
                     echo 'Elemento ',$Node->nodeName, ' Teu Seu Valor: ', $Node->nodeValue != NULL ? $Node->nodeValue : 'Nulo', '<br />';
            }
   }
?>

Como todos já entenderam o retorno do getElementsByTagName, quando usado em um Loop, não retorna o objeto de DOMNodeList

Pois, pra cada elemento ou ( item ) de album, vai ser passado para uma instancia de DOMElement, como $Nodes ..

é DOMElement extende DOMNode .. que tem suas propiedades aonde são armazenados objetos de DOMElement, 'childNodes' propiedade de DOMNode

corresponde a todos os elementos filhos de 'album' no caso .. , continuando na nossa onda .. childNodes retorna DOMElement novamente

onde temos +2 propidades que identificam cada elemento .. e seus parentes, valores, etc ..

 

nodeName = retorna o nome do elemento do tipo atual
nodeValue = o valor do elemento, dependendo de seu tipo
parentNode = retorna o elemento parente do elemento atual
firstChild = retorna o primeiro filho do elemento atual ( se houver )
lastChild = retorna o ultimo filho do elemento atual ( se houver )
previousSibling = O elemento imediatamente anterior ao elemento atual
nextSibling = O elemento imediatamente após ao elemento atual
attributes = retorna o objeto de DOMNamedNodeMap contendo o(s) attibuto(s) do elemento atual

Entre outras propiedades ..

DOMNode :seta: http://br2.php.net/manual/en/class.domnode.php#domnode.props.nodename

Contendo referencias de cada attributo, caso desejem ver exemplos !

 

Enfi, .. voltando ao assunto, a Saída de ambos Loops, foi exatamente

Elemento capa Teu Seu Valor: Nulo

Elemento foto Teu Seu Valor: Nulo

Elemento foto Teu Seu Valor: Nulo

Elemento foto Teu Seu Valor: Nulo

Elemento foto Teu Seu Valor: Nulo

Elemento foto Teu Seu Valor: Nulo

É está exatamente certa, nenhum elemento tem valor, tempos apenas attributos setados para esses elementos ..

então, no exemplo acima já mostrei como você chegam no NODE e seus Respectivos Valores :P

Ok, vamos pegar o attributo desses elementos, da mesma forma que chegamos em cada filho de 'album'

Podemos pegar o attributo de cada filho de 'album' simplesmente !

<?php
  foreach( $DOMDocument->getElementsByTagName( 'album' ) as $Nodes ){
            foreach( $Nodes->childNodes as $Node ){
                     echo $Node->nodeName, ' Attributo id = ', $Node->getAttribute( 'id' ), 
                          ' | Attributo classificação = ', $Node->getAttribute( 'classificacao' ),
                          ' | Attibuto src = ', $Node->getAttribute( 'src' ), '<br />';
            }     
   }
?>

então nosso output sería

capa Attributo id = | Attributo classificação = | Attibuto src = meuPrimeiroAlbum.jpg

foto Attributo id = 1 | Attributo classificação = 5 | Attibuto src = umaFoto1.jpg

foto Attributo id = 2 | Attributo classificação = 5 | Attibuto src = umaFoto2.jpg

foto Attributo id = 3 | Attributo classificação = 4 | Attibuto src = umaFoto3.jpg

foto Attributo id = 4 | Attributo classificação = 2 | Attibuto src = umaFoto4.jpg

foto Attributo id = 5 | Attributo classificação = 1 | Attibuto src = umaFoto5.jpg

 

Continua na parte 2 galeria .. ja vou começar a escrever .. como fazer outras coisas com DOMDocument, até !

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ótima iniciativa, só acho que você poderia diminuir a quantidade de "então" ^_^

 

Porém eu, particularmente, prefiro a XmlWriter para escrever XML's

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.