Ir para conteúdo

POWERED BY:

Arquivado

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

Renato Augusto

Criar array de um xml

Recommended Posts

Olá amigos tudo bem?

 

Estou apanhando para conseguir ler os campos de um XML e jogar SOMENTE os que eu quero para um array.

 

Na função abaixo comecei fazendo o que EU achava certo, mas parei no meio (onde está comentado) por não saber como continuar. Alguém pode dar uma luz?

 


$retorno = array();

function criaArray($q) {
$result = file_get_contents("http://search.4shared.com/network/searchXml.jsp?searchExtention=mp3&q=" . $q);
$xml = simplexml_load_string($result);

foreach ($xml->{'result-files'}->file as $musicas) {
   	foreach ($musicas as $key => $value) {

       	/*Aqui faz algo que retorna a variavel $retorno em um array do tipo
			* array(
			* array('nome' => 'Nome da musica', 'url' => 'URL do campo flash-preview-url do xml'),
			* array('nome' => 'Nome da musica', 'url' => 'URL do campo flash-preview-url do xml'),
			* array('nome' => 'Nome da musica', 'url' => 'URL do campo flash-preview-url do xml'),
			* array('nome' => 'Nome da musica', 'url' => 'URL do campo flash-preview-url do xml'),
			* 
			* );
			* 
			* 
			*/

   	}
}
}

 

Abaixo um exemplo de XML que a URL retorna.

 

<!--<?xml version="1.0" encoding="UTF-8"?>-->
<search-result>
<query>mixverao</query>
<total-files>1</total-files>
<page-number>1</page-number>
<pages-total>0</pages-total>
<start>0</start>
<files-per-page>10</files-per-page>
<files-approx-count>1</files-approx-count>
<result-files>
   	<file>
       	<name>Dj_Gabriel_Cabral_(MixVerao_Janeiro_10).mp3</name>
       	<description>DJ Gabriel Cabral (MixVerão)</description>
       	<downloads-count>60</downloads-count>
       	<upload-date-format>hh:mm dd-MM-yyyy</upload-date-format>
       	<upload-date>10:18 20-01-2010</upload-date>
       	<url>http://www.4shared.com/mp3/UgEfe-pE/Dj_Gabriel_Cabral__MixVerao_Ja.htm</url>
       	<preview-url />
       	<flash-preview-url>http://dc168.4shared.com/img/202795439/1fbf78ff/dlink__2Fdownload_2FUgEfe-pE_3Ftsid_3D20120413-045520-822fac8a/preview.mp3?dsid=1fs6qo.e81d3c0fb688680389a5fb52e5edec8a</flash-preview-url>
       	<user>DJ Gabriel Cabral</user>
       	<profile-url>http://www.4shared.com/u/QVyX58Co/DJ_Gabriel_Cabral.html</profile-url>
       	<size>10,670 KB</size>
   	</file>
</result-files>
</search-result>

Compartilhar este post


Link para o post
Compartilhar em outros sites

Usando DOMDocument é fácil :thumbsup:

 

<?php

$DOMDocument = new DOMDocument( '1.0', 'UTF-8' );
$DOMDocument->preserveWhiteSpace = false;
$DOMDocument->load( 'http://search.4shared.com/network/searchXml.jsp?searchExtention=mp3&q=' );
$result = array( );

foreach( $DOMDocument->getElementsByTagName( 'file' ) as $content )
{
   $search = array( );

   foreach( $content->childNodes as $child )
   {        
       if( $child->nodeName == 'name' or $child->nodeName == 'flash-preview-url' )
       {
           $search[ $child->nodeName ] = $child->nodeValue;
       }
   }
   $result[ ] = $search;
}

var_dump( $result );

 

Saída

 

 

array
 0 => 
   array
     'name' => string 'quando eu fico bravo.gif' (length=24)
     'flash-preview-url' => string '' (length=0)
 1 => 
   array
     'name' => string 'IMG_0209.PNG' (length=12)
     'flash-preview-url' => string '' (length=0)
 2 => 
   array
     'name' => string 'shrek.gif' (length=9)
     'flash-preview-url' => string '' (length=0)
 3 => 
   array
     'name' => string '1179278506080gw1.gif' (length=20)
     'flash-preview-url' => string '' (length=0)
 4 => 
   array
     'name' => string '4shared_desktop_3.3.5.exe' (length=25)
     'flash-preview-url' => string '' (length=0)
 5 => 
   array
     'name' => string '4shared_Desktop_3.3.5M.exe' (length=26)
     'flash-preview-url' => string '' (length=0)
 6 => 
   array
     'name' => string 'LMFAO - S-e-x-y And I Know It [ vortex1.blogfa.com].mp4' (length=55)
     'flash-preview-url' => string 'http://dc352.4shared.com/img/1152723645/ab85cbda/dlink__2Fdownload_2Fxw_5FJpO9Y_2FLMFAO_5F-_5FS-e-x-y_5FAnd_5FI_5FKnow_5FIt_5F.mp4_3Ftsid_3D20120413-100234-704cab17/preview.flv?dsid=1fs6qo.78ff9ae12023ac62bd43bfe1c0a8edb8' (length=221)
 7 => 
   array
     'name' => string '4sync_1.0.2.exe' (length=15)
     'flash-preview-url' => string '' (length=0)
 8 => 
   array
     'name' => string 'desktop4shared-1.3.dmg' (length=22)
     'flash-preview-url' => string '' (length=0)
 9 => 
   array
     'name' => string 'Pixote - Ficando Louco ( 2012 OFICIAL ).mp3.gif' (length=47)
     'flash-preview-url' => string '' (length=0)

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

É, to vendo o lindo poder desse DOMDocument! :lol:

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não, a DOMDocument é consideravelmente mais devagar do que a SimpleXML pelo fato de a responsabilidade de cada componente ser de uma classe nativa diferente.

 

Pelo exemplo do Carlos você vê apenas a DOMDocumment mas, por exemplo, DOMDocumment::getElementsByTagName() retorna um DOMNodeList o qual através de seu método DOMNodelist::item() retorna um DOMNode.

 

Para o bê-a-bá, você não precisa entender toda mecânica da coisa, mas conforme a necessidade aumenta, conhecer cada componente é fundamental, até mesmo para você saber quais métodos estarão disponíveis e em que parte do código.

 

Bons estudos :thumbsup:

Compartilhar este post


Link para o post
Compartilhar em outros sites

Usando o DOMDocumment, como pegar em uma variavel o campo do XML (total-files)? tenho que fazer outro for? ou é só

 

$numArquivos =  $DOMDocument->getElementsByTagName('total-files'); 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não, você não precisa de outro loop. Eu poderia orientar você a ler os métodos da DOMDocumment, mas seria crueldade demais para uma coisa tão simples:

 

$DOMDocument -> getElementsByTagName( 'total-files' ) -> item( 0 ) -> nodeValue

Obs: a variável $DOMDocument é a mesma do exemplo do Carlos.

 

E veja só como esse exemplo ilustra bem a separação de responsabilidades que eu citei.

 

Cada método invocado pertence à uma classe diferente, mas como cada uma é o retorno da anterior, a cadeia de invocação ("flechas sequenciais") pode ser usada até que cheguemos à propriedade pública com a informação em si.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olha eu outra vez!

 

Com a ajuda do @Bruno Augusto e do @Carlos Coelho fiz a classe abaixo para um projeto que quero liberar, mas estou com um problema. O 4shared é horrível para organizar seus ficheiros. Determinadas buscas podem retornar elementos que não são músicas. Para resolver isso é fácil, basta olhar se no node -> flash-preview-url possui alguma valor, caso não tenha significa que o elemento não é uma música então não deve entrar no array de retorno.

 

Tentei fazer isso com o unset() porém como é um array multidimensional ele retorna sempre os outros arrays mesmo nulos.

 

Dúvida: Como faço então para que só entrem no array resultado os elementos que realmente tiverem um flash-preview-url?

 

Olha a classe que fiz ai:

 

 

 

 


<?php

/**
* Classe que realiza uma busca e retorna
* os dados em um array para posterior manipulação.
* 
* @version 0.1 
* @access public  
*/
Class Busca {

/**
	* Controla se existe algum erro na busca
	* 
	* @access public
	* @name $erro
	*/
public $erro = FALSE;

/**
	* Armazena o resultado da busca feito pelo usuário
	* 
	* @access public
	* @name $resultado
	*/
public $resultado = array();

/**
	* Retorna Array com nome e url das músicas encontradas
	* 
	* @param string $busca a busca do usuário
	* @param int $pag a pagina ser listada, por padrão a primeira
	* 
	* @return array
	*/
public function fazBusca($busca, $pag = 1) {

   	$busca = urlencode($busca); //Converte caracteres não-alfanuméricos

   	$DOMDocument = new DOMDocument('1.0', 'UTF-8');
   	$DOMDocument->preverseWhiteSpace = TRUE;
   	$DOMDocument->load('http://search.4shared.com/network/searchXml.jsp?searchExtention=mp3&q=' . $busca . '&start=' . $pag);

   	$totalArquivos = $DOMDocument->getElementsByTagName('total-files')->item(0)->nodeValue;

   	if($totalArquivos) {
       	foreach ($DOMDocument->getElementsByTagName('file') as $arquivo) {
           	$temp = array();

           	foreach ($arquivo->childNodes as $campo) {


               	if ($campo->nodeName == 'name') {
                   	$temp['nome'] = $this->formataNome($campo->nodeValue);
               	}
               	if ($campo->nodeName == 'flash-preview-url' && $campo->nodeValue <> NULL) {
                   	$temp['download'] = $this->encodeURL($campo->nodeValue);
                   	$temp['url'] = $campo->nodeValue;
               	}else{
                 	unset($temp); // Não adianta :( 
               	}


           	}// segundo foreach
           	$this->resultado[] = $temp;
       	}// Primeiro foreach
   	} else {
       	$this->erro = TRUE;
   	}
}

// class

/**
	* Retorna a url de download codificada em base64
	* 
	* @param string $url URL do link de download
	* 
	* @return string
	*/
public function encodeURL($url) {
   	return base64_encode($url);
}

/**
	* Remove a extensão dos nomes e formata
	* 
	* @param string $nome nome completo encontrado no 4shared
	* 
	* @return string
	*/
public function formataNome($nome) {

   	return str_replace('.mp3', '', $nome);
}

}



 

 

 

Desculpa ai as ratas típicas de um iniciante, mas acredito que o código está ate bom.

 

 

 

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Da linha 58 a linha 53 eu tenho:

 

if ($campo->nodeName == 'flash-preview-url' && $campo->nodeValue <> NULL) {
                   	$temp['download'] = $this->encodeURL($campo->nodeValue);
                   	$temp['url'] = $campo->nodeValue;
               	} else {
                   	unset($temp);
               	}

 

Isso faz com que os valores só sejam jogados na variável, se o flash-preview-url existir. ate aqui tudo ótimo, mas o nome, mesmo sem o flash-preview-url, existe.

 

minha ideia foi usar um if para testar antes de atribuir o nome, mas ai descobri que depois de passar por um node, ele não volta, então se o teste do nome estiver dentro de um teste do node da url nao rola.

 

então o que quero mesmo é, que o teste ao encontrar o node nulo destrua o array atual. como ele é multidimensional so a tual é eliminada, caso tenha valores em outros nodes o retorno é normal, mas ignora todo node sem a bendita url.

 

Pegou?

 

array(

 

array( ' essa tem dados tanto nome quanto url '),

 

array( ' opa essa nao tem todos dados deve ser eliminada ' ),

 

array(' essa tb esta ok ')

 

)

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.