Autor Zpráva
vasio
Profil *
Ahoj, načítám soubor s velkým množstvím řádků(2.7miliónů), je to soubor xml struktury a mělo by v něm být něco kolem 5 tisíc řádků s nepárovím elementem
<radek name="..." />
- a já bych potřeboval je spočítat. Mají se spočítat řádky jen s určitým name="" a jen nepárové. Data se načítají metodou DOM, potřebuji to jen kvůli kontrolnímu součtu.... jinak bych použil SAX(rychlost....). Díky za nápovědu. :-)
Alphard
Profil
vasio:
Můžete sen dát ukázku toho souboru? Jde mi o to, jestli lze z jednoho řádku poznat, jestli je hledaný, nebo ne. Z [#1] se mi zdá, že ano. Pokud obsahuje správné name a na konci />, nalezeno.

Potom bych to viděl na
$count = 0;
$hn = fopen('soubor.xml', 'r');
while (!feof($hn))
{
  $buffer = fgets($hn);
  if (find($buffer))
  {
    $count++;
  }
}
fclose($hn);
vasio
Profil *
Jistě, stáhnout....

totiž ulice je tam npř: jako <ulice nazev="K LIPANŮM" kod="8931" /> a v ní nejsou žádné č. p. a tyto ulice potřebuji spočítat.

Potřebuji to nějak zadat do DOMu:
$dom = new DomDocument();
$dom->load('adresy.xml');
$koren = $dom->documentElement;

$_count = 0;

zpracovat_potomky( $koren, &$_count );
function zpracovat_potomky( $uzel, $_count )
{
    $children = $uzel->childNodes;
    foreach ( $children as $prvek ) {
      if ( $prvek->nodeType == XML_ELEMENT_NODE ) {
        if ( $prvek->nodeName == 'ulice' ) {
          $_count++;
        }
        zpracovat_potomky( $prvek, &$_count );
      }
   }
}

echo $_count;


a před inkrementaci $_count ještě přijde zmiňovaná( hledaná ) podmínka která bude vracet true při nepárovém elementu, díky .)
vasio
Profil *
Pro ty co mají zájem zkusit mi pomoci tak zasílám Adresy.xml
a kód ze kterého doporučuji začít(pro mne ideální):
 <?php
  date_default_timezone_set('Europe/Prague');
  $a = date( 'U' );
  set_time_limit(0);

  $dom = new DomDocument();
  $dom->load('adresy.xml');
  $koren = $dom->documentElement;

  $_count = 0;

  zpracovat_potomky( $koren, &$_count );
  function zpracovat_potomky( $uzel, $_count )
  {
      $children = $uzel->childNodes;
      foreach ( $children as $prvek ) {
	if ( $prvek->nodeType == XML_ELEMENT_NODE ) {
	  if ( $prvek->nodeName == 'ulice' ) {
	    $_count++;
	  }
	  zpracovat_potomky( $prvek, &$_count );
	}
    }
  }

  $b = date( 'U' );
  $c = $b - $a;
  echo $c . ' sekund | ' . $_count . 'x byla nalezena ulice bez c.p. ';
?>


Moc uvítám jakoukoli pomoc.
Alphard
Profil
Abych pravdu řekl, stále nevím, co přesně hledat.
Našel jsem 5384 nepárových tagů ulice, např. <ulice nazev="K LIPANŮM" kod="8931" />, podmínky jsem určil dle [#3].
Jestli je to blbost, tak prosím příklad toho, co se má hledat :-)
vasio
Profil *
Není to blbost ale očekával jsem číslo o 54 větší. Jak jste to zjistil? Teď si budu ještě muset spočítat nepárové obce a casti a budu doufat že mi to dá číslo 54 :-D. Tak zatim díky :-)
Alphard
Profil
vasio:
Jak jste to zjistil?
Vyšel jsem ze svého [#2], parsovat celé xml se mi zdálo zbytečné. (Dle zadání potřebuji pouze počet, nic jiného.) Zatímco váš kód se mi zpracovával cca 20 sekund bez chybějících kontrol, můj byl hotový za 4 sekundy i s nimi :-) Obsazenou paměť jsem neměřil, ale nenačítání celého souboru by mělo být výrazně šetrnější.

V tom vašem kódu jsou chybně použité reference (minimálně pro PHP 5.2, jak to bylo dříve už nevím).
& má být v definici funkce a při jejím voládní už ne, takže
function zpracovat_potomky( $uzel, &$_count ) {}
zpracovat_potomky( $koren, $_count );

Můj kód (velice jednoduchý, nebyl jsem si jist, jestli chápu zadání):
<?php
$startTime = microtime(true);
$count = 0;
$hn = fopen('adresy.xml', 'r');
while (!feof($hn))
{
  $buffer = fgets($hn);
  //if (preg_match('~<ulice(.*)/>~', $buffer))  // tohle trvalo 2x déle než strpos
  if (strpos($buffer, '<ulice') !== false && strpos($buffer, '/>'))
  {
    $count++;
  }
}
fclose($hn);

$endTime = microtime(true);

echo "Nalezeno $count výsledků<br>\n";
echo "Dokončeno za ".number_format($endTime - $startTime, 2, ',', ' ')."<br>\n";
Vygenerovaný výstup:
Nalezeno 5384 výsledků
Dokončeno za 4,14


Když je to správně, zkusím to někdy (možná) přepsat do procházení DOM.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

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