Autor Zpráva
gardener
Profil
Zdravim, zkousim si napsat jedoduchou mobilni aplikaci ale mam trochu problem s parsovanim nekterych hodnot z XML.

Pokud vyhledavam podle IC:
wwwinfo.mfcr.cz/cgi-bin/ares/darv_std.cgi?ico=27074358

Zasilam request pomoci Ajaxu a v PHP parsuji nasledovne:

if(!empty($ico)&&is_numeric($ico))
{
define('ARES','http://wwwinfo.mfcr.cz/cgi-bin/ares/darv_bas.cgi?ico=');



$file = @file_get_contents(ARES.$ico);
if ($file) $xml = @simplexml_load_string($file);
$a = array();
if ($xml) {
 $ns = $xml->getDocNamespaces();
 $data = $xml->children($ns['are']);
 $el = $data->children($ns['D'])->VBAS;
 if (strval($el->ICO) == $ico) {
  $a['ico']     = strval($el->ICO);
  $a['dic']     = strval($el->DIC);
  $a['firma']     = strval($el->OF);
  $a['ulice']    = strval($el->AA->NU).' '.strval($el->AA->CO);
  $a['mesto']    = strval($el->AA->N);
  $a['psc']    = strval($el->AA->PSC);
  $a['stav']     = 'ok';
 } else
  $a['stav']     = 'IC firmy nebylo nalezeno';
} else
 $a['stav']     = 'Databáze ARES není dostupná';
echo json_encode($a);

}



Problem je ale kdyz Vyhledvam podle obchodnicho jmena..to mi take vrati XML, ktery bych pak rad dal vypisoval ale zde mi z nej nejde nic vydolovat:

Odkaz:
wwwinfo.mfcr.cz/cgi-bin/ares/ares_es.cgi?xml=1&obch_jm=Jan%20Novak

if(!empty($obchodni_jm))
{
define('ARES','http://wwwinfo.mfcr.cz/cgi-bin/ares/darv_bas.cgi?obch_jm=');

$file = @file_get_contents(ARES.$obchodni_jm);
if ($file) $xml = @simplexml_load_string($file);
$a = array();
if ($xml) {
 $ns = $xml->getDocNamespaces();
 $data = $xml->children($ns['are']);
 $el = $data->children($ns['S'])->VBAS;
 if (strval($el->ICO) == $obchodni_jm) {
  $a['ico']     = strval($el->ICO);
  $a['jmeno']     = strval($el->ojm);
  $a['firma']     = strval($el->jmn);

  $a['stav']     = 'ok';
 } else
  $a['stav']     = 'IC firmy nebylo nalezeno';
} else
 $a['stav']     = 'Databáze ARES není dostupná';
echo json_encode($a);
}



Hlavne netusim jak nacist cely node tech zaznamu (oproti vyhledavani podle IC jich muze byt vraceno vice) a vratit ti tak abychom to pomhl pomoci Json zpracovat uz dal.

Kdyby nekdo tusil jak toto vyresit budu moc vdecny za kazdou radu.
YoSarin
Profil
gardener:
Oprav prosímtě ten druhý odkaz ať neukazuje na www.example.com...
A jestli jsi na to koukal, tak druhý odkaz neobsahuje téměř žádné konkrétní informace (kromě obchodního názvu, ares identifikátoru, adresy a občas IČa), tak není divu že to z něj nemůžeš vyparsovat...

edit:
Navíc koukám, že url u problematického příkladu se liší - první (ta co odkazuje na example.com) vrací seznam všech Janů Nováků, druhá (ta co je v kódu) vrací chybu
gardener
Profil
Opraveno, pardon. Pokud bych ale vypisoval jen ty s IC, coz je vetsina, tak na to IC mohu dat vpodstate akci na overeni IC (k tomu abych zjistil detaily), druha fce ma primarne slouzit k tomu aby kdyz nekde chce zjistit jestli nejaky novak je treba z Aše, tak se koukne a hned to muze videt..
YoSarin
Profil
gardener:
A teď ještě ujasni kterou z těch dvou url opravdu používáš - tu co obsahuje ares_es.cgi nebo tu s darv_bas.cgi?
gardener
Profil
Pravda, to jsem uplne prehlidnul. V tom druhem pripade ma byt pouzita:


Nicmene aplikace mi nevrati ani chybu ani O.K

if(!empty($obchodni_jm))
{
define('ARES','http://wwwinfo.mfcr.cz/cgi-bin/ares/ares_es.cgi?xml=1&obch_jm=');

$file = @file_get_contents(ARES.$obchodni_jm);
if ($file) $xml = @simplexml_load_string($file);
$a = array();
if ($xml) {
 $ns = $xml->getDocNamespaces();
 $data = $xml->children($ns['are']);
 $el = $data->children($ns['S'])->VBAS;
 if (strval($el->ICO) == $obchodni_jm) {
  $a['ico'] 	= strval($el->ICO);
  $a['jmeno'] 	= strval($el->ojm);
  $a['firma'] 	= strval($el->jmn);

  $a['stav'] 	= 'ok';
 } else
  $a['stav'] 	= 'IC firmy nebylo nalezeno';
} else
 $a['stav'] 	= 'Databáze ARES není dostupná';
echo json_encode($a);
}




A v jquery volam:


    $(document).ready(function(){
            
            
            
            
                $('#writeout').hide();
                
                $("#verify").live("click", function(event, ui){
                    var ico = $('#ico').val();
                    
					
					//IF ICO IS NUMBER
                    if (ico.match(/^\d{8,}$/)) {
                        
									$.ajax({
                        url: "http://www.web.cz/dev/overeni-ico/ares.php",
                        contentType: "application/json; charset=utf-8",
                        dataType: "json",
                        data: "ico=" + ico,
                        cache: false,
                        success: function(data){
                            if (data.stav == 'ok') {
                                $('#dic').html(data.dic);
                                $('#firma').html(data.firma);
                                $('#ulice').html(data.ulice);
                                $('#mesto').html(data.mesto);
                                $('#psc').html(data.psc);
                                
                                alert('Zadané IČ je platné, informace se zobrazí níže.');
                                $('#writeout').show();
                                $('ul').listview('refresh');
                            }
                            else {
                                alert(data.stav);
                            }
                        },
                    });
					
                        
                    }
                    //IF ICO IS NAME OF SUBJECT
                    else {
                        
						alert("Jmeno");
						$.ajax({
                        url: "http://www.web.cz/dev/overeni-ico/ares.php",
                        contentType: "application/json; charset=utf-8",
                        dataType: "json",
                        data: "obchodni_jm=" + ico,
                        cache: false,
                        success: function(data){
                            if (data.stav == 'ok') {
                                $('#dic').html(data.dic);
                                $('#firma').html(data.firma);
                                $('#ulice').html(data.ulice);
                                $('#mesto').html(data.mesto);
                                $('#psc').html(data.psc);
                                
                                alert('Zadané IČ je platné, informace se zobrazí níže.');
                                $('#writeout').show();
                                $('ul').listview('refresh');
                            }
                            else {
                                alert(data.stav);
                            }
                        },
                    });
					
						
                    }
                    
                    
					// alert(ico);
                    
					
		
					
                });
             
YoSarin
Profil
a když odstraníš ten @ před simplexml_load_string($file); tak to taky nic nevypíše?
Medvídek
Profil
gardener:
Že se nezeptáš Radka Hulána, když už si od něj zkopíroval ten kód :)
gardener
Profil
Medvídek:
Protože se simple XML nemám skoro žádné zkušenosti a tady to přeci jen bude znát více lidí?
YoSarin:
Ten by tam měl být uvedený jestli se nepletu nebo ne?
YoSarin
Profil
gardener:
ten @ znamená "mute" - jediné co dělá je to, že funkce která je bezprostředně za ním napsaná má potlačené vypisování chybových hlášek. Tzn. že tam může docházet k chybě, která se ti nikde nezobrazí.
gardener
Profil
Ach so, zapamatuju si.
Nicmene i potom je prubeh stejny, je videl, ze neco se to snazi nacist, jelikoz jinak by skript vratil
 $a['stav'] 	= 'Databáze ARES není dostupná';


Chyba nejspise nastane zde:

 if (strval($el->ICO) == $obchodni_jm) {
  $a['ico'] 	= strval($el->ICO);
  $a['jmeno'] 	= strval($el->ojm);
  $a['firma'] 	= strval($el->jmn);

  $a['stav'] 	= 'ok';
 } else
  $a['stav'] 	= 'IC firmy nebylo nalezeno';




Jelikoz se uz nevrati ani
 $a['stav'] 	= 'ok'; ani   $a['stav'] 	= 'IC firmy nebylo nalezeno';
YoSarin
Profil
A co vypíše var_dump($el);?
gardener
Profil
var_dump vraci prazdnou hodnotu, kdyz jsem ale skript zmensil jen na kontrolu podle obc.h jmena>

<?php

$obchodni_jm = "Jan Novak";

if(!empty($obchodni_jm))
{
define('ARES','http://wwwinfo.mfcr.cz/cgi-bin/ares/ares_es.cgi?xml=1&obch_jm=');

$file = @file_get_contents(ARES.$obchodni_jm);
if ($file) $xml = simplexml_load_string($file);
$a = array();
if ($xml) {
 $ns = $xml->getDocNamespaces();
 $data = $xml->children($ns['are']);
 $el = $data->children($ns['S'])->VBAS;
 var_dump($el);
 
 if (strval($el->ICO) == $obchodni_jm) {
  $a['ico'] 	= strval($el->ICO);
  $a['jmeno'] 	= strval($el->ojm);
  $a['firma'] 	= strval($el->jmn);

  $a['stav'] 	= 'ok';
 } else
  $a['stav'] 	= 'IC firmy nebylo nalezeno';
} else
 $a['stav'] 	= 'Databáze ARES není dostupná';
echo json_encode($a);
}


?>


Dostanu v php skriptu hlasku>

object(SimpleXMLElement)#5 (0) { } {"stav":"IC firmy nebylo nalezeno"}

Tazke si myslim, ze hledam xml elementy se spatnym nazvem, nebo minimalne uzel. Jenze kvuli odlisne strukture XML oproti vyhledavani pres ico se nemohu zorientovat v tom, co hledat jako prvni.
gardener
Profil
Opravdu nikdo netusi, jak to pomoci simpleXML vyparsovat?
YoSarin
Profil
gardener:
VBAS tam podle mne nemá co dělat - v tomhle xml ten element vůbec není... místo něj je tam S, tak zkus:
 $el = $data->children($ns['S']);
 var_dump($el);
gardener
Profil
Tak po uprave>
$ns = $xml->getDocNamespaces();
 $data = $xml->children($ns['are']);
 $el = $data->children($ns['S']);
 var_dump($el);


Dostanu pozmenenou chubovou hlasku>
object(SimpleXMLElement)#4 (0) { } {"stav":"IC firmy nebylo nalezeno"}

skoro to vypada, ze jeste odebrat 4 elementy a mohlo by to jit..
YoSarin
Profil
$ns = $xml->getDocNamespaces();
 $data = $xml->children($ns['are']);
 $el = $data->children($ns['dtt'])->S; // pokud nepůjde ->S, tak zkusit ->V
 var_dump($el);
gardener
Profil
Ja uz jsem take zkousel nejake kombinace ale nic..soucasny kod na vyhledavani dle jmena vypada takto:

<?php

$obchodni_jm = "Jan Novak";

if(!empty($obchodni_jm))
{
define('ARES','http://wwwinfo.mfcr.cz/cgi-bin/ares/ares_es.cgi?xml=1&obch_jm=');

$file = @file_get_contents(ARES.$obchodni_jm);
if ($file) $xml = simplexml_load_string($file);
$a = array();
if ($xml) {
 $ns = $xml->getDocNamespaces();
 $data = $xml->children($ns['are']);
 $el = $data->children($ns['dtt'])->S; // pokud nepůjde ->S, tak zkusit ->V
 var_dump($el);
 
 if (strval($el->ICO) == $obchodni_jm) {
  $a['ico'] 	= strval($el->ICO);
  $a['jmeno'] 	= strval($el->ojm);
  $a['firma'] 	= strval($el->jmn);

  $a['stav'] 	= 'ok';
 } else
  $a['stav'] 	= 'IC firmy nebylo nalezeno';
} else
 $a['stav'] 	= 'Databáze ARES není dostupná';
echo json_encode($a);
}


?>


Nemelo by se spise pracovat s
<are:Odpoved> 
?
YoSarin
Profil
1. máš zapnuté zobrazování chyb?
2. necháváš si zobrazovat všechny chyby?
3. odstraň ten @ před file_get_contents

Když si zkusíš otevřít tu adresu v prohlížeči - jak rychle se ti načítá? Mě strašně pomalu. Když jsem si ten kód pustil u sebe, vyústilo to v
Warning: file_get_contents(http://wwwinfo.mfcr.cz/cgi-bin/ares/ares_es.cgi?xml=1&obch_jm=jan%20novak) [function.file-get-contents]: failed to open stream: HTTP request failed! in C:\weby\skripts\ares.php on line 6
.
A funkční kód:
define('REFRESH_TIME', 3600 * 24 * 7); // doba po kterou budeš načtené údaje držet v cache
define('TMP_PATH', ''); // tady si nadefinuj cestu kam chceš ukládat nacachovaná data - apache tam musí mít právo zápisu

// tady zkusíme cache - jestli jsme stejná data z aresu v nedávné době (jeden týden) už netahali
$localFile = TMP_PATH . 'ares.preloaded.' . md5($obchodni_jm) . '.tmp';
if (!file_exists($localFile) || filemtime($localFile) <= (time() - REFRESH_TIME)) {
	// pokud jsme tato konkrétní data ještě nehledali, nebo od posledního updatu uběhla příliš dlouhá doba, načteme si je z API
	define('ARES','http://wwwinfo.mfcr.cz/cgi-bin/ares/ares_es.cgi?xml=1&obch_jm=');
	
	// nastavíme si timeout pro file_get_contents na trochu vyšší hodnotu, páč API je děsně pomalé
	$ctx = stream_context_create(array(
		'http' => array(
			'timeout' => 60
			)
		)
	); 

	$file = file_get_contents(ARES . $obchodni_jm, false, $ctx);
	if ($file) {
		// uložíme získaná data do lokálního souboru
		file_put_contents($localFile, $file);
	}
} else {
	// máme-li platnou cache načteme data z ní
	$file = file_get_contents($localFile);
}

if ($file) {
	$xml = simplexml_load_string($file);
	if ($xml) {
		$ns = $xml->getDocNamespaces();
		$data = $xml->children($ns['are']);
		$el = $data->children($ns['dtt'])->V;
		foreach ($el->S as $item) {
			// zpracuj si data podle potřeby
			echo '<xmp>' . print_r($item, true) . '</xmp>';
		}
	} else {
		// XML se nepodařilo načíst - nějaká chyba
	}
} else {
	// došlo k chybě připojení, nebo se nepodařilo soubor stáhnout či přečíst z nějakého jiného důvodu
}
echo json_encode($a);
gardener
Profil
YoSarin:
1. máš zapnuté zobrazování chyb?
Mám
2. necháváš si zobrazovat všechny chyby?
Na locale ano, na testovacim serveru ne
3. odstraň ten @ před file_get_contents
Odstraneno

Když si zkusíš otevřít tu adresu v prohlížeči - jak rychle se ti načítá? Mě strašně pomalu.
Mě vcelku rychle, skoro hned.

Tvuj uvedeny kod mi ale pro hodnotu "Jan Novak" vraci NULL, tobe ne?
YoSarin
Profil
gardener:
Zkoušel jsem to s $obchodni_jm = 'jan%20novak'; A vypadla mi hromada výsledků...
gardener
Profil
YoSarin:
Máš pravdu, zapomněl jsem v tom vyhledávaném řetězci nahradit mezery.

Díky moc za pomoc.

Vaše odpověď


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0