Autor Zpráva
JardaR
Profil
Zdravím, rád bych požádal o pomoc. Kdysi jsem si vytvořil kód pro načtení XML soubory s daty, ale dodavatel mi nyní změnil XML strukturu se kterou si nevím rady.

Příklad:
<?xml version="1.0" encoding="UTF-8" ?> 
<pricelist description="XML soubor" date="18. 2. 2011, 15:16">
 <pricelist_items>
  <item_category name="Krystaly">
   <item_category name="AM">
    <item code="1MA3600" ean="8595241328133" brand="Krystal HK" price="90,30" retail="139,00" availability="N">Krystal AM 27MHz Rx</item> 
   </item_category>
   <item_category name="HITEC original">
    <item_category name="TX">
     <item code="1HI7043" ean="" brand="Hitec" price="122,70" retail="199,00" availability="N">X-tal Rx AM 27 MHz přijímačový</item> 
     <item code="1HI90100" ean="0669962435611" brand="Hitec" price="122,70" retail="199,00" availability="N">X-tal Rx 61 Singl 35.010 MHz HITEC</item> 
     <item code="1HI90102" ean="0669962435628" brand="Hitec" price="122,70" retail="199,00" availability="1">X-tal Rx 62 Singl 35.020 MHz HITEC</item> 
    </item_category>
    <item_category name="RX-single">
     <item code="1HI7043" ean="" brand="Hitec" price="122,70" retail="199,00" availability="N">X-tal Rx AM 27 MHz přijímačový</item> 
     <item code="1HI90100" ean="0669962435611" brand="Hitec" price="122,70" retail="199,00" availability="N">X-tal Rx 61 Singl 35.010 MHz HITEC</item> 
     <item code="1HI90102" ean="0669962435628" brand="Hitec" price="122,70" retail="199,00" availability="1">X-tal Rx 62 Singl 35.020 MHz HITEC</item> 
    </item_category>
   </item_category> 
  </item_category>
 </pricelist_items>
</pricelist>


Pomocí třídy phpXML version 1.0 od Michaela P. Mehla mám následující kód:
<?php
if ($_POST['action'] == 'import') {
	if (is_uploaded_file($_FILES['xml_file']['tmp_name'])) {
		$xml = new XML($_FILES['xml_file']['tmp_name']);
		$products = $xml->evaluate("//item_category");

   foreach ($products as $param) {
     $t = $xml->get_attributes($param);
     $category = $t['name'];
     $category = iconv('utf-8','windows-1250',$category);
     $t = $xml->get_attributes($param."/item[1]");
     $id = $t['code'];
     echo "Kategorie: " . $category . "<br />";
     echo "Kód: " . $id . "<br />";
   }
  } 
}
?>


Ten mi ale nyní vypisuje toto:

Kategorie: Krystaly
Kód:
Kategorie: AM
Kód: 1MA3600
Kategorie: HITEC original
Kód:
Kategorie: TX
Kód: 1HI7042
Kategorie: RX-single
Kód: 1HI7043

což je vpodstatě na základě uvedeného php dobře, ale potřebuji abych z XML dostal i všechna data ze značek ITEM a ne vždy pouze tu první.
Dále mě tam mate, že ani nerozlišuje kategorie a podkategorie a všechny mají značku ITEM_CATEGORY. Lze i toto nějakým způsobem vycucnout abych byl schopen podkategorie odlišit?
JardaR
Profil
Tak nakonec jsem to předělal pomocí xml_parse, třeba to někomu pomůže. Ještě musím dodělat ukládání do databáze.
<?php
if ($_POST['action'] == 'import') {
	if (is_uploaded_file($_FILES['xml_file']['tmp_name'])) {
    $soubor = $_FILES['xml_file']['tmp_name'];

  function PocatecniZnacka ($parser, $nazev, $atributy) {
    global $kat;
    if ($nazev == "ITEM_CATEGORY") {
      echo "Kategorie " . $atributy[NAME] . "<br />";
      $kat = $atributy[NAME];
    }
    if ($nazev == "ITEM") {
      echo "Kategorie " . iconv('utf-8','windows-1250', $kat);
      echo " Kód " . $atributy[CODE];
      echo " Nákupní cena " . $atributy[PRICE];
      echo " Prodejní cena " . $atributy[RETAIL];
    }
  }
  function KoncovaZnacka ($parser, $nazev) {
    //echo "Koncová " . $nazev . " - ";
    //echo print_r($atributy)."<BR>";
  }
  function characters($parser, $data) {
    if (trim($data) != "") {
      echo " Název " . iconv('utf-8','windows-1250', trim($data)) . "<br />";
    }
  }
  $parser=xml_parser_create(); // vytvoření instance parseru
  xml_set_element_handler ($parser, "PocatecniZnacka", "KoncovaZnacka"); // řekneme parseru, co má udělat když se dostane k počátečnímu elementu
  xml_set_character_data_handler($parser, "characters"); // nastavení funkce pro obsluhu obsahu elementu
  if (!($obsah_souboru = fopen($soubor, "r"))) die("Nelze otevřít XML soubor pro načtení dat."); // otevření souboru
  while ($data = fread($obsah_souboru, 500)) { // čtení souboru
    if (!xml_parse($parser, $data, feof($obsah_souboru))) { // a předání dat parseru
        die(sprintf("XML chyba: %s na řádku %d", 
                    xml_error_string(xml_get_error_code($xml_parser)), 
                    xml_get_current_line_number($xml_parser))); 
    } 
  }
  xml_parser_free($parser); // uvolnění paměti alokované parserem
  } 
}
?>


Kód zatím dělá výpis na obrazovku, abych věděl kam se co ukládá a co se kde děje. Učím se za pochodu. :-)

S jednou věcí asi budu potřebovat pomoci. Pokud zpracovávám 10.řádek XML (viz. 1.příspěvek), tak výstup vypadá takto:
Kategorie TX Kód 1HI7042 Nákupní cena 122,70 Prodejní cena 199,00 Název X-tal Tx AM 27 MHz p
Název řijímačový

tzn., že ten druhý řádek tam nemá co dělat. Rozdělí text elementu na 2 části před českým znakem. Pokud zruším diakritiku, tak je výstup vpořádku:
Kategorie TX Kód 1HI7042 Nákupní cena 122,70 Prodejní cena 199,00 Název X-tal Tx AM 27 MHz prijimacovy
JardaR
Profil
Ještě bych dodal, že pokud upravím kód a nechám vypsat obsah pole, tak dostanu také toto:
    [0] => Array
        (
            [cdata] => X-tal Tx AM 27 MHz p
        )

    [1] => Array
        (
            [cdata] => řijímačový
        )


Nějak nechápu. S kódováním jsem si již hrál, ale bez úspěchu.
JardaR
Profil
Tak jsem na to přišel:

  function characters($parser, $data) {
    global $obsah;
    if (trim($data) != "") {
      $obsah[0] .= $data;
    }
  }

tudíž načítat postupně do pole a zobrazit až ve funkci KoncovaZnacka s definicí proměnné pole global $obsah. Samozřejmě nezapomenout na
$obsah = array();

Stejných dotazů jsem našel kvanta a řešení ne. Tak snad pomůže. Údajně se problém projevuje až ve verzi PHP 5, ale podrobnosti jsem nezjišťoval.

Vaše odpověď


Prosím používejte diakritiku a interpunkci.

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

0