Forwardfeed's blog

rozmaitości

Gadu API – parsowanie XMLa

without comments

Mamy XML i co teraz z nim zrobić aby uzyskać dane które nas interesują. Przykład pokazuje jedynie sposób wyciągnięcia danych z formatu XML w łopatologiczny sposób. Profesjonalna metoda autoryzacji jest podlinkowana na końcu tego wpisu.

Poniżej nieco zmodyfikowany kod z poprzedniego wpisu traktującego o Gadu API

<?php
$fp = fsockopen("ssl://external-services.gadu-gadu.pl", 443, $errno, $errstr, 30);
if (!$fp) {
    echo "$errstr ($errno)<br />\n";
} else {
    //w przeciwnym wypadku
    $out = "GET /botmaster/getToken/11111111 HTTP/1.1\r\n";  //tworzymy komunikat
    $out .= "Authorization: Basic aW1pZS5uYXp3aXNrb0Bkb21lbmEucGw6aGFzbG9fZG9fdXp5c2thbmlhX3Rva2VudQ==\r\n";
    $out .= "Host: external-services.gadu-gadu.pl\r\n";
    $out .= "Accept: */*\r\n\r\n";
 
 
    fwrite($fp, $out);
 
    while (!feof($fp)) {
        $stream .= fgets($fp, 128); //ZMIENIONA LINIA; zamiast wyswietlania lapiemy wszystkie dane od servera do zmiennej
    }
    fclose($fp);
}

Powyższy kod rozszerzony został o możliwość parsowania danych w formacie XML dodając następujące komendy:

//NOWY KOD -----------------------------------------------------------------------------------
//1
$begin = strpos($stream,'<'); //wiedzac ze xml posrod tych danych zaczyna sie od znaku < szukamy gdzie wystepuje pierwszy
$end = strrpos($stream,'>'); //i ostatni
 
$code = substr($stream, $begin, $end - $begin+1 );  //wycinanmy kod pomiedzy pierwszym <, a ostatnim>
//1---
//2
class dane_autoryzacyjne{  //tworzymy prosta klase do przechowywania danych
      var $token;
      var $server;
      var $port;
}
 
$dane = new dane_autoryzacyjne; //tworzymy obiekt klasy dane_autoryzacyjne
//2----
//3
function tagBeg($parser, $attr,  $params){ //funkcja callbackowa obsługująca znaczniki otwierające
      global $act_tag;      
      $act_tag = $attr;      
}
 
function tagEnd($parser, $attr){  //funkcja callbackowa obsługująca znaczniki zamykające
    ;
 }
 
function tagBet($parser, $text){  //funkcja callbackowe obsługująca tekst pomiędzy znacznikami
      global $act_tag, $dane;
         switch($act_tag){
            case 'TOKEN': $dane -> token .= $text; break;
            case 'SERVER': $dane -> server .= $text; break;
            case 'PORT': $dane -> port .= $text; break;
      }
   }
//3-----
//4
$parser = xml_parser_create();
xml_set_element_handler($parser, 'tagBeg', 'tagEnd');
xml_set_character_data_handler($parser, 'tagBet');
 
 
xml_parse($parser, $code);
 
xml_parser_free($parser);
//4-----
echo $dane ->token. " " .$dane ->server. " " .$dane ->port;
 
?>

Przykład z poprzedniego wpisu, w przybliżeniu zwraca wartość taką jak poniżej:

HTTP/1.1 200 OK
Connection: close
Transfer-Encoding: chunked
Content-Type: text/xml
Date: Tue, 17 Nov 2009 19:37:25 GMT
Server: lighttpd

<?xml version=”1.0″ encoding=”UTF-8″?>
<botmaster>
<token>
22222222
</token>
<server>
botapi-3.gadu-gadu.pl
</server>
<port>
80
</port>
</botmaster>

Dane do obróbki w tym przypadku są przechowywane w zmiennej $stream. W obszarze //1 pozbywamy się nagłówka HTTP i dzięki temu zostaje nam czysty XML. Wycinamy ze zmiennej $stream kawałek łańcucha znaków od pierwszego < do ostatniego >.

Dzięki temu w zmiennej $stream zostaje nam:

<?xml version=”1.0″ encoding=”UTF-8″?><botmaster><token>22222222</token><server>botapi-3.gadu-gadu.pl</server><port>80</port></botmaster>

W drugiej sekcji tworzymy prostą klasę, w której można przechowywać podstawowe dane potrzebne do autoryzacji: token, serwer i port. Potem tworzony jest obiekt $dane dla naszych danych.

Następnie w //3 części definiowane są funkcje callbackowe wykorzystywane przez parser XML. Funkcja tagBeg($parser, $attr, $params) będzie wywoływana w każdym momencie gdy znacznik XML będzie otwierany przez parser. Funkcja ta przyjmuje standardowe parametry, takie jak uchwyt stworzonej instancji parsera $parser, nazwę rozpatrywanego znacznika $attr, oraz tablicę parametrów dla rozpatrywanego znacznika $params. W tym przypadku nie ma tablicy z dodatkowymi parametrami, która przykładowo mogła wyglądać by tak: <botmaster numer_botmastera = “1″>. W zmiennej $act_tag przechowywany jest rozpatrywany aktualnie znacznik. Jest to zmienna globalna, która jest widziana w innych funkcjach.

Funkcja tagEnd($parser, $attr) jest wywoływana w momencie zamykania znacznika XML. W tym przypadku nie robi nic, w najprostszym przypadku może powiadamiać o statusie parsowania XML np. echo “zamknięto znacznik”.$attr;.

Funkcja tagBet($parser, $text) przyjmuje jako parametr uchwyt do instancji parsera $parser oraz tekst $text zawarty pomiędzy znacznikami. Dzięki zmiennej $act_get wiemy, którym zmiennym z obiektu $dane przypisać wartość ze zmiennej $text.

W ostatniej części tworzymy obiekt $parser, a następnie kojarzymy wykonywanie określonych funkcji tagBeg, tagEnd, tagBet w reakcji na wystąpienie konkretnego zdarzenia: znacznika otwierającego/zamykającego lub tekstu pomiędzy znacznikami. Funkcja xml_parse() parsuje nasz kod XML. Wywołując kolejno funkcje callbackowe zmienne są przypisywane do pól naszego obiektu $dane. Na końcu zwalniane są zasoby związane z naszym parserem za pomocą funcji xml_free().

Naturalnie można to wszystko rozwiązać tak jak jest to zrobione w pliku PushConnection.php w klasie BotAPIAuthorization do ściągnięcia tutaj z wystawionym gotowym interfejsem do wysyłania wiadomości. Łatwo i przejrzyście bez rozbijania każdego elementu na drobne tak jak w tym i poprzednim wpisie. Przykład wykorzystania wspomnianej klasy znajduje się tutaj.

Popularity: 3%

  • Twitter
  • Reddit
  • Slashdot
  • Facebook
  • Digg
  • WordPress
  • StumbleUpon
  • LinkedIn
  • Delicious
  • Blogger Post
  • Google Reader
  • Google Bookmarks
  • Share/Bookmark

Związane

Written by Krzysztof Dziądziak

Grudzień 8th, 2009 at 4:15 pm

Leave a Reply