Autor Zpráva
nethor
Profil
Zdravím,
řeším tento problém:

1. stánout zabalené XML (gz)
2. rozbalit
3. převést na pole
4. serializovat
5. výsledek uložit do souboru

Vším jsem se prokousal, ale mám problém s alokací paměti a rychlostí.
Rozbalená XML mají klidně i 60 MB, s nastavením memory_limit pod 512M nejdou zpracovat a i tak to trvá dlouho 20 ~ 30s.

Z nějakého důvodu nefunguje zpracování přes simplexml_load_file() protože jsou ve jménech tagů dvojtečky např. <obi:NutsLau>CZ0513564290</obi:NutsLau>
Script vrací něco jako
object(SimpleXMLElement)#6 (1) {
  ["comment"]=>
  object(SimpleXMLElement)#8 (0) {
  }
}

Po nahrazení ":"za "-" <obi-NutsLau>CZ0513564290</obi-NutsLau> simplexml_load_file() už funguje,
ale zmíněná úprava je opět náročná na paměť.

Není u simplexml_load_file nějaká direktiva, aby fce brala i dvojtečky ?
(Možná to nějak souvisí s NameSpace , ale nevím jak..)

.. nebo jiný nápad jak na to?
Alphard
Profil
Záleží na konkrétní podobě XML, teď jsem zkoušel převést na pole 35MB xml soubor a podařilo se mi to za cca 1.5 s se spotřebou cca 70 MB, tj. dvojnásobek. Víc bez kódu neporadím.

Z nějakého důvodu nefunguje zpracování přes simplexml_load_file() protože jsou ve jménech tagů dvojtečky
To jsou namespace. Nejlepší je jít na to přes metodu children, viz blog.sherifmansour.com/?p=302.
nethor
Profil
Jedno z menších XML je zabalené tady: vdp.cuzk.cz/vymenny_format/soucasna/20151130_OB_554499_UKSH.xml.gz

Orientačně část kódu po rozbalení:
<?xml version="1.0" encoding="UTF-8"?>
<vf:VymennyFormat xsi:schemaLocation="urn:cz:isvs:ruian:schemas:VymennyFormatTypy:v1 ../ruian/xsd/vymenny_format/VymennyFormatTypy.xsd" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ami="urn:cz:isvs:ruian:schemas:AdrMistoIntTypy:v1" xmlns:base="urn:cz:isvs:ruian:schemas:BaseTypy:v1" xmlns:coi="urn:cz:isvs:ruian:schemas:CastObceIntTypy:v1" xmlns:com="urn:cz:isvs:ruian:schemas:CommonTypy:v1" xmlns:kui="urn:cz:isvs:ruian:schemas:KatUzIntTypy:v1" xmlns:kri="urn:cz:isvs:ruian:schemas:KrajIntTypy:v1" xmlns:mci="urn:cz:isvs:ruian:schemas:MomcIntTypy:v1" xmlns:mpi="urn:cz:isvs:ruian:schemas:MopIntTypy:v1" xmlns:obi="urn:cz:isvs:ruian:schemas:ObecIntTypy:v1" xmlns:oki="urn:cz:isvs:ruian:schemas:OkresIntTypy:v1" xmlns:opi="urn:cz:isvs:ruian:schemas:OrpIntTypy:v1" xmlns:pai="urn:cz:isvs:ruian:schemas:ParcelaIntTypy:v1" xmlns:pui="urn:cz:isvs:ruian:schemas:PouIntTypy:v1" xmlns:rsi="urn:cz:isvs:ruian:schemas:RegSouIntiTypy:v1" xmlns:spi="urn:cz:isvs:ruian:schemas:SpravObvIntTypy:v1" xmlns:sti="urn:cz:isvs:ruian:schemas:StatIntTypy:v1" xmlns:soi="urn:cz:isvs:ruian:schemas:StavObjIntTypy:v1" xmlns:uli="urn:cz:isvs:ruian:schemas:UliceIntTypy:v1" xmlns:vci="urn:cz:isvs:ruian:schemas:VuscIntTypy:v1" xmlns:vf="urn:cz:isvs:ruian:schemas:VymennyFormatTypy:v1" xmlns:zji="urn:cz:isvs:ruian:schemas:ZsjIntTypy:v1" xmlns:voi="urn:cz:isvs:ruian:schemas:VOIntTypy:v1"><!--
  v 1.0 - základní verze
--><vf:Hlavicka><vf:VerzeVFR>1.6</vf:VerzeVFR><vf:TypZaznamu>Platne</vf:TypZaznamu><vf:TypDavky>Plna</vf:TypDavky><vf:TypSouboru>OB_UKSH</vf:TypSouboru><vf:Datum>2015-12-01T00:47:52</vf:Datum><vf:TransakceOd><com:Id>0</com:Id><com:Zapsano>2012-06-29T01:36:44</com:Zapsano></vf:TransakceOd><vf:TransakceDo><com:Id>1018280</com:Id><com:Zapsano>2015-11-30T23:50:27</com:Zapsano></vf:TransakceDo><vf:Metadata xlink:type="simple" xlink:href="http://cuzk.cz/ruian/metadata/20151130_OB_564290_UKSH.xml"></vf:Metadata><vf:PlatnostDatK><com:ISUI>2015-11-30T23:50:27</com:ISUI><com:ISKN>2015-11-30T23:00:17</com:ISKN></vf:PlatnostDatK></vf:Hlavicka><vf:Data>
<vf:Obce>
<vf:Obec gml:id="OB.564290"><obi:Kod>564290</obi:Kod><obi:Nazev>Osečná</obi:Nazev><obi:StatusKod>3</obi:StatusKod><obi:Okres><oki:Kod>3505</oki:Kod></obi:Okres><obi:Pou><pui:Kod>1775</pui:Kod></obi:Pou><obi:PlatiOd>2013-06-03T00:00:00</obi:PlatiOd><obi:IdTransakce>234490</obi:IdTransakce><obi:GlobalniIdNavrhuZmeny>410877</obi:GlobalniIdNavrhuZmeny><obi:MluvnickeCharakteristiky><com:Pad2>Osečné</com:Pad2><com:Pad3>Osečné</com:Pad3><com:Pad4>Osečnou</com:Pad4><com:Pad6>Osečné</com:Pad6><com:Pad7>Osečnou</com:Pad7></obi:MluvnickeCharakteristiky><obi:VlajkaText>Červený list s bílou hlavou gryfa se žlutou zbrojí a korunou. Poměr šířky k délce listu je 2:3.</obi:VlajkaText><obi:ZnakText>V červeném štítě stříbrná korunovaná hlava gryfa se zlatou zbrojí.</obi:ZnakText><obi:NutsLau>CZ0513564290</obi:NutsLau><obi:Geometrie><obi:DefinicniBod><gml:MultiPoint gml:id="DOB.564290" srsName="urn:ogc:def:crs:EPSG::5514" srsDimension="2"><gml:pointMembers><gml:Point gml:id="DOB.564290.1"><gml:pos>-698577.00 -980779.00</gml:pos></gml:Point></gml:pointMembers></gml:MultiPoint></obi:DefinicniBod><obi:OriginalniHranice><gml:MultiSurface gml:id="HOB.564290" srsName="urn:ogc:def:crs:EPSG::5514" srsDimension="2"><gml:surfaceMember><gml:Polygon gml:id="HOB.564290.1"><gml:exterior><gml:LinearRing>
<gml:posList>-700878.78 -977354.65 -700859.80 -977324.30 -700832.95 -977287.40 -700820.20 -977264.30 -700790.80 -977206.50 -700785.60 -977195.85 -700769.30 -977172.82 -700740.50 -977145.85 -700671.80 -977104.00 -700647.68 -977083.29 -700626.80 -977065.37 -700573.10 -977033.00 -700548.40 
...

Při postupu dle „blog.sherifmansour.com/?p=302
jsem shořel v tom cyklu:
$xml = simplexml_load_file("tmp/145132187156816a0f27576.xml");
foreach ($xml as $entry){    // $xml  prom. je prakticky prázdná, není co cyklit. 
  $namespaces = $entry->getNameSpaces(true);
  $kui = $entry->children($namespaces['kui']); 
  echo $kui->Kod;
  echo $kui->Nazev;
}
Dílčí úspěch pouze:
$xml = simplexml_load_file("tmp/145132187156816a0f27576.xml");
echo "<xmp>";
var_dump($xml->getNameSpaces(true););
echo "</xmp>";


PS: hodnoty, ke kterým se potřebuji dostat jsou dost vnořené, např.
$this->Data["vf:VymennyFormat"]["vf:Data"]["vf:KatastralniUzemi"]["vf:KatastralniUzemi"]["kui:Kod"][$key] ;
$this->Data["vf:VymennyFormat"]["vf:Data"]["vf:KatastralniUzemi"]["vf:KatastralniUzemi"]["kui:Geometrie"]["kui:OriginalniHranice"]["gml:MultiSurface"]["gml:surfaceMember"]["gml:Polygon"]["gml:exterior"]["gml:LinearRing"]["gml:posList"][$key]    ;
nethor
Profil
Tak jsem to nakonec rozlousknul.
Dost zákeřná zrada je, že u simplexml nefunguje normálně var_dump() &spol.
Finální kód:
class Xml { 

    public     $File    ;
    public     $Xml    ;    
    public     $ParseArr     = array()    ;

    function __construct($File)    { 
        $this->File = $File    ;
        $this->Xml = simplexml_load_file($this->File);
    } 

    function Parse(){
        $this->ParseArr = array();

        $Node = $this->Xml->children("vf",true)->Data->KatastralniUzemi->KatastralniUzemi    ;
        foreach ($Node as $key=>$value) {    
            $Kod         = (string)$value->children("kui",true)->Kod    ;    
            $this->ParseArr[$Kod]["Kod"]     = $Kod    ;
            $this->ParseArr[$Kod]["Name"] = (string)$value->children("kui",true)->Nazev    ;
            $this->ParseArr[$Kod]["Point"] = (string)$value->children("kui",true)->Geometrie->DefinicniBod->children("gml",true)->MultiPoint->pointMembers->Point->pos    ;
            $this->ParseArr[$Kod]["Area"] = (string)$value->children("kui",true)->Geometrie->OriginalniHranice->children("gml",true)->MultiSurface->surfaceMember->Polygon->exterior->LinearRing->posList ;
        }
          return $this->ParseArr    ;
    }    

} 
Nároky na paměť minimální , doba zpracování kolem 1s, což je přijatelné. Výsledné lokání soubory se serializovanými poli mají kolem 100KB,
takže načtení je řádově v desetinách s.

Mám dojem, že by se hodilo použít xpath(), ale to jsem nerozchodil. Nevadí, takhle to splňuje účel.

Alphard:
Díky za nakopnutí.

Vaše odpověď

Mohlo by se hodit

Odkud se sem odkazuje


Prosím používejte diakritiku a interpunkci.

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