Ir para conteúdo

Arquivado

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

Andrey Knupp Vital

DOMDocument - XML { PHP }, Parte 3

Recommended Posts

Olá novamente galera !, como na Parte 2 já falamos de como encontramos elementos no Documento através do DOMXPath .. acho que agora vocês já tem uma noção de como a banda toca ..

já podemos ler o RSS do iMasters usando DOMXPath .. o RSS do Fórum de PHP, fica armazenado na seguinte URL

http://forum.imasters.com.br/rss/forums/2-forum-php/, Oque tem a seguinte estrutura em seu XML

 

 

iMastersXMLBlur.jpg

 

 

 

é uma estrutura simples, fácil .. nem precisamos de DOMXPath para percorrer, mais pra ficar mais interessante..

já que no XML, nos não temos como identificar quem POSTOU tal tópico, que tal identificarmos esse Alguém ? ..

Aí sim, teria utilidade em usar o DOMXPath nessa situação, iremos fazer ele carregar o HTML do fórum, aonde temos a estrutura

das tabelas, com algumas informações sobre o Tópico, mais pra não tumultuar , vamos pegar apenas quem postou, e o link do perfil do usuário

ok.. temos a ideia de como fazer, agora vamos botar em pratica ..

<?php
       /*
        * Nova instancia de DOMDocument
        */
       $DOMDocument = new DOMDocument( '1.0', 'utf-8' );
       /*
        * Não preservar espaços em branco redundantes
        */
       $DOMDocument->preserveWhiteSpace = false;
       /*
        * Carrega o XML com o link do RSS do Forum 
        */
       $DOMDocument->load( 'http://forum.imasters.com.br/rss/forums/2-forum-php/' );
       /*
        * Apos Carregado, nova instancia de DOMXPath
        */
       $DOMXPath = new DOMXPath( $DOMDocument );
       /*
        * Então, faço uma consulta, que no caso seria
        * ./ = elemento raiz { <rss> } 
        *  /channel = elemento filho de { rss }
        *  /item = elemento filho de channel, e pai de qualquer tag que esteje dentro dele
        * [1] Exibir apenas o primeiro.. Apenas pra output 
        */
       foreach( $DOMXPath->query(".//channel/item[1]") as $RSSNodes ){
                /*
                 * Então como já cheguei nos filhos de item
                 * Pra cada um deles, vai ser attribuido a variavel $RSSNode ..
                 * Como já expliquei na parte1, ->nodeValue, resgata o valor dos elementos.
                 */
                foreach( $RSSNodes->childNodes as $RSSNode ){
                         echo utf8_decode( $RSSNode->nodeValue ), '<hr>';
                }
       }

 

O Output é

PHP + LDAP
http://forum.imasters.com.br/topic/433054-php-ldap/
Estou postando, obviamente, pela consideracao q tenho no forum ,e por ja ter pesquisado e nao achado a respota que necessito...

ja vi varios scrits aki no forum sobre conexao, cadastro de usuario no AD do windows, mas nenhum informa como pegar o usuario da maquina e jogar no sistema, ex..

o cara chega na empresa, loga a sua maquina, beleza...ae eu keria pegar este usuario ja logado em sua maquina e autenticar no AD, sem ter que o cara digitar sua senha novamente, alguem poderia me dar uma luz?
Fri, 13 May 2011 16:30:19 +0000
http://forum.imasters.com.br/topic/433054-php-ldap/

 

Certamente, outra coisa que vejo, e que a data de publicação do POST armazenada em 'pubDate', não está correta

pra isso usaremos strftime, strtotime para converter para o nosso horário, mais temos que ver também o Horário de verão

o nosso timezone atual de acordo com Brasília, é GMT-3 ..

Ok, já estamos com os dados dos nodes do XML, vamos passar para um array, para trabalharmos melhor =)

<?php
               foreach( $RSSNodes->childNodes as $RSSNode ){
                         $RSSData[$RSSNode->nodeName] = $RSSNode->nodeValue;
                }
                $RSSiMasters[] = $RSSData;

Fiz apenas está modificação no código, então executei com um print_r, em RSSiMasters, a saída foi

?>
Array
(
   [0] => Array
       (
           [title] => PHP + LDAP
           [link] => http://forum.imasters.com.br/topic/433054-php-ldap/
           [description] => Estou postando, obviamente, pela consideracao q tenho no forum ,e por ja ter pesquisado e nao achado a respota que necessito...
           ja vi varios scrits aki no forum sobre conexao, cadastro de usuario no AD do windows, mas nenhum informa como pegar o usuario da maquina e jogar no sistema, ex..
           o cara chega na empresa, loga a sua maquina, beleza...ae eu keria pegar este usuario ja logado em sua maquina e autenticar no AD, sem ter que o cara digitar sua senha novamente, alguem poderia me dar uma luz?
           [pubDate] => Fri, 13 May 2011 16:30:19 +0000
           [guid] => http://forum.imasters.com.br/topic/433054-php-ldap/
       )

)

Beleza, já temos o nosso Array com os dados de cada post lançado no RSS do Fórum .. podemos estilizar com um CSS pra ficar bacaninha ..

mais agora, que já temos a informação de cada post no RSS, vamos descobrir quem publicou cada tópico..

<?php
           /*
            * Não para os Loops apos 60 Segundos
            */
           set_time_limit(0);
           /*
            * Seta um timezone pra Área atual
            */
           date_default_timezone_set('America/Sao_Paulo');
           /*
            * Captura o localtime 
            */
           $hour = localtime(time(), true);
           /*
            * Verifica se existe a chave tm_isdst que corresponde ao horario de verão
            * se nao existir e -3 horas na formatação da data ..
            */
           $hdv = $hour['tm_isdst'] ? '-2 hour' : '-3 hour';
           /*
            * Nova instancia de DOMDocument
            */
           $DOMDocument = new DOMDocument( '1.0', 'utf-8' );
           /*
            * Não preservar espaços em branco redundantes
            */
           $DOMDocument->preserveWhiteSpace = false;
           /*
            * Carrega o XML do forum de PHP
            */
           $DOMDocument->load( 'http://forum.imasters.com.br/rss/forums/2-forum-php/' );
           /*
            * Nova instancia de DOMXPath apos o XML Carregado
            */
           $DOMXPath = new DOMXPath( $DOMDocument );
           /*
            * Então faço uma procura normalmente pelos tópicos 
            */
           foreach( $DOMXPath->query(".//channel/item") as $Nodes ){
                    /*
                     * Percorre todos os filhos de 'item'
                     * E grava no Array as informaçoes
                     */
                    foreach( $Nodes->childNodes as $Node ){
                             $RSSiMasters[ $Node->nodeName ] = $Node->nodeValue;
                    }
                    $RSSData[] = $RSSiMasters;
           }
             /*
              * Carrega o HTML do Forum, usado @, pra ignorar alguns erros de Entidades HTML
              * Não prejudica em nada ..
              */
            @$DOMDocument->loadHTML( file_get_contents("http://forum.imasters.com.br/forum/3-php/") );
             /*
              * Nova instancia de DOMXPath para o HTML Do Forum ..
              */
             $DOMXPathHTML = new DOMXPath( $DOMDocument );
             echo '<div id="rssBox">';
             /*
              * Percorrer todos os índices do Array $RSSData
              */
             for( $i = 0; $i < sizeOf($RSSData); ++$i ){
                   /*
                    * Então, é logica simples, você tendo cada ITEM com um respectivo LINK
                    * do XML, beleza, e so procurar por esses Links no HTML do forum .. 
                    * Quando achar os links, volta pro seus parentes .. pra procura da TD onde se encontra 
                    * a informação que queremos, o elemento <a> com o nome de Usuario, é o link do seu Perfil
                    */
                   foreach( $DOMXPathHTML->query(".//td/a[@href='".$RSSData[$i]['link']."'][@class='topic_title']/parent::node()/parent::node()/td/a[@hovercard-ref=\"member\"][@class='_hovertrigger']") as $hNodes ){
                     /*
                      * Salva em um array os links do perfil de usuario
                      * Não usado em childNodes, porque <a> não tem filhos, então seria procurar
                      * por um attributo onde o mesmo não existe, so presisamos percorrer os filhos 
                      * em busca do nodeValue de <a>, que tem o nome de usuario 
                      */
                     $userLinks[] = $hNodes->getAttribute('href');
                     foreach( $hNodes->childNodes as $hNode ){
                              $userData['user'] = utf8_decode($hNode->nodeValue);
                     }
                     /*
                      * Monta o array com os usuarios  
                      */
                     $users[] = $userData;
                   }
                   /*
                    * Então dentro do for, já exibo cada UL, Li de cada <item> no XML
                    * Juntamente a quem Postou .. 
                    */
                   echo '<ul class="rssData">';
                            echo '<li class="title">Titulo do Tópico |', '<a href="'.$RSSData[$i]['link'].'">', utf8_decode($RSSData[$i]['title']), '</a></li>';
                            echo '<li class="publicadoEm">Postado Por:<a href="'.$userLinks[$i].'"> ', $users[$i]['user'] ,'</a> Em ', strftime('%d %B %A %Y, %H:%M:%S', strtotime($RSSData[$i]['pubDate'])), '</li>';
                   echo '</ul>';

              }
           echo '</div>';
?>

Ok, após o código executado ..

A Data Formatada correta-mente pro horário em que foi postado

Temos o seguinte resultado

<div id="rssBox">
   <ul class="rssData">
       <li class="title">Titulo do Tópico |<a href="http://forum.imasters.com.br/topic/433054-php-ldap/">PHP + LDAP</a></li>
       <li class="publicadoEm">Postado Por:<a href="http://forum.imasters.com.br/user/44096-igorphp/"> Igor.php</a> Em 13 maio sexta-feira 2011, 13:30:19</li>
   </ul>
</div>

 

;)

 

Quem quiser um exemplo online, Clique aqui

Abraços

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bacana o artigo, vi que diminuiu os "então" ( ^^ ) e ficou melhor.

 

Mas, duas coisas:

 

Porque você faz isso:

 

foreach( $DOMXPath->query(".//channel/item") as $Nodes ){
                    /*
                     * Percorre todos os filhos de 'item'
                     * E grava no Array as informaçoes
                     */
                    foreach( $Nodes->childNodes as $Node ){
                             $RSSiMasters[ $Node->nodeName ] = $Node->nodeValue;
                    }
                    $RSSData[] = $RSSiMasters;
           }

Ao invés de:

 

$query = $DOMXPath->query(".//channel/item");

$length = $query -> length;

$RSSData = array();

for( $i = 0; $i = $length; $i += 1 ) {
   $RSSData[ $query -> item( $i ) -> nodeName ] = $query -> item( $i ) -> nodeValue;
}

Escrevi agora e não pude testar o código todo então pode haver alguma besteira minha nisso :P

 

E segundo, pra que esse parser manual dos links? Cada nó <item> tem um nó filho <link> pronto para uso?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Primeiro: so pelo nodeName alí, você já podia ter visto .

Você tá colocando em um array varias tags iguais, link, description.. etc, sabendo que não ia repetir as tags dentro do array =). iá sobrepondo uma a uma ate chegar no ultimo, o outro array impede isso, você tem a contagem de todos os elementos '[]' , e então so addiciona cada filho de item a essa contagem ..

 

Segundo: seu loop tá errado, ia dar loop infinito mesmo assim, trocando pra

$query = $DOMXPath->query(".//channel/item");
$length = $query->length;
$RSSData = array();
for( $i = 0; $i < $length; $i++ ) {
   $RSSData[ $query -> item( $i ) -> nodeName ] = $query -> item( $i ) -> nodeValue;
}

Que é o certo, ia mostrar so 1 item do RSS, é mesmo assim não ia ter as outras chaves no array

ia cuspir uma chave 'item' pra todos os filhos de 'item', que é errado

 

Terceiro:

E segundo, pra que esse parser manual dos links? Cada nó <item> tem um nó filho <link> pronto para uso?

 

Isso é pra pegar o autor do tópico, é o link de perfil dele.. :P , já que no RSS não tem quem postou =)

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.