Autor | Zpráva | ||
---|---|---|---|
lokix Profil |
Zdravím všechny na fóru,
mám na Vás dotaz, radu či postup jak přečíst z xml souboru kde jsou produkty s klasickými popisy i obsah v atributech param. Vzorový soubor má krom klasických atributů (ean, img, price, tad...) i atributy param_name ve kterých je ještě param ze kterého chci dostat udaje do db. Script dole umožňuje co chci až právě na ty param-y. Ty nejsou nijak odlišeny: <param>sklo</param><param>kulatý</param>atd... Zkoušel jsem pod-foreach další: foreach ($xml->SHOPITEM->PARAM[1]->VAL as $v3) {$param2 = $v3;} ... foreach ($xml->SHOPITEM->PARAM[11]->VAL as $v13) {$param12 = $v13;} ale do db se k údajům uloží sice všechny správně ale jen z 1 řádku. Snad jsem problém popsal dost podrobně a najde se zde někdo kdo by poradil či popostrčil. Předem momc díky za jakýkoliv nápad. foreach ($xml->SHOPITEM as $v) { $produkt = htmlspecialchars($v->PRODUCT, ENT_QUOTES); $ean = $v->EAN; $url = $v->URL; $price = $v->PRICE; $vat = $v->VAT; $delivery = $v->DELIVERY_DATE; $img = $v->IMGURL; $img2 = $v->IMGURL[1]; $img3 = $v->IMGURL[2]; $img4 = $v->IMGURL[3]; $img5 = $v->IMGURL[4]; $cattext = $v->CATEGORYTEXT; $manufacturer = $v->MANUFACTURER; foreach ($xml->SHOPITEM->PARAM[0]->VAL as $v2) {$param = $v2;} /* foreach ($xml->SHOPITEM->PARAM[1]->VAL as $v3) {$param2 = $v3;} foreach ($xml->SHOPITEM->PARAM[2]->VAL as $v4) {$param3 = $v4;} foreach ($xml->SHOPITEM->PARAM[3]->VAL as $v5) {$param4 = $v5;} foreach ($xml->SHOPITEM->PARAM[4]->VAL as $v6) {$param5 = $v6;} foreach ($xml->SHOPITEM->PARAM[5]->VAL as $v7) {$param6 = $v7;} foreach ($xml->SHOPITEM->PARAM[6]->VAL as $v8) {$param7 = $v8;} foreach ($xml->SHOPITEM->PARAM[7]->VAL as $v9) {$param8 = $v9;} foreach ($xml->SHOPITEM->PARAM[8]->VAL as $v10) {$param9 = $v10;} foreach ($xml->SHOPITEM->PARAM[9]->VAL as $v11) {$param10 = $v11;} foreach ($xml->SHOPITEM->PARAM[10]->VAL as $v12) {$param11 = $v12;} foreach ($xml->SHOPITEM->PARAM[11]->VAL as $v13) {$param12 = $v13;} */ $qry = "INSERT into product (`product`, `ean`, `url`, `price`, `vat`, `delivery_date`, `img_url`, `img_url2`, `img_url3`, `img_url4`, `img_url5`, `category_text`, `manufacturer`, `urceni`, `cifernik`, `reminek`, `pouzdro`, `luminiscence`, `funkce`, `tvar_pouzdra`, `vodotesnost`, `rozmery`, `styl`, `typ_strojku`, `sklo`) values ('$produkt', '$ean', '$url', '$price', '$vat', '$delivery', '$img', '$img2', '$img3', '$img4', '$img5', '$cattext', '$manufacturer', '$param', '$param2', '$param3', '$param4', '$param5', '$param6', '$param7', '$param8', '$param9', '$param10', '$param11', '$param12')"; $ret=mysql_query($qry) or die (mysql_error()); } |
||
Tori Profil |
lokix:
„zkoušel jsem pod-foreach další: [...] ale do db se k údajům uloží sice všechny správně ale jen z 1 řádku.“ Asi byste měl na ř.15 místo foreach ($xml->SHOPITEM->PARAM[0]->VAL as $v2) použít foreach ($v->PARAM[0]->VAL as $v2) , abyste pokaždé pracoval s tímtéž produktem, jako ve vnějším foreach.
K ukládání: Máte možnost ovlivnit podobu toho XML? (Abyste např. měl <param type="barva">zelená</param> <param type="tvar_pouzdra">kulaté</param> ... )
I v současném stavu by to ale mělo jít zapsat jednodušeji. Zkuste něco takového: // místo řádků 15-30 včetně $params = $v->PARAM; // array_walk($params, 'mysql_real_escape_string'); // funguje jen pokud $params je pole, nikoli objekt $qry = "INSERT into product (`product`, `ean`, `url`, `price`, `vat`, `delivery_date`, `img_url`, `img_url2`, `img_url3`, `img_url4`, `img_url5`, `category_text`, `manufacturer`, `urceni`, `cifernik`, `reminek`, `pouzdro`, `luminiscence`, `funkce`, `tvar_pouzdra`, `vodotesnost`, `rozmery`, `styl`, `typ_strojku`, `sklo`) values ('$produkt', '$ean', '$url', '$price', '$vat', '$delivery', '$img', '$img2', '$img3', '$img4', '$img5', '$cattext', '$manufacturer', '$params[0]', '$params[1]', '$params[2]', '$params[3]', '$params[4]', '$params[5]', '$params[6]', '$params[7]', '$params[8]', '$params[9]', '$params[10]', '$params[11]')"; $ret = mysql_query($qry) or die (mysql_error()); |
||
lokix Profil |
Tori:
Moc děkuji "opět" za radu. XML parsuji přes simplexml a níže je celý script, který funguje se už blíží té funkční podobě. Nyní to ukládá tak jak má, ale z ostrého xml jsem zjistsil, že param-ů bude mít každý produkt různě což je hrůza. Podobu ovlivnit nemůžu je to od velkoskladu a já to potřebuji "pouze" importovat. Pod kódem přikládám vzorové xml, ale jak jsem psal nebudu znát dopředu počet param-ů takže max je jich 12, ale někde jen 9. Pokud můžete Tori byl bych rád za nakopnutí či pomoc. Script require_once "/inc/config/config.inc.php"; // připojení db $xml = simplexml_load_file("ukazka.xml"); // načten í xml foreach ($xml->SHOPITEM as $v) { $produkt = htmlspecialchars($v->PRODUCT, ENT_QUOTES); $ean = $v->EAN; $url = $v->URL; $price = $v->PRICE; $vat = $v->VAT; $delivery = $v->DELIVERY_DATE; $img = $v->IMGURL; $img2 = $v->IMGURL[1]; $img3 = $v->IMGURL[2]; $img4 = $v->IMGURL[3]; $img5 = $v->IMGURL[4]; $cattext = $v->CATEGORYTEXT; $manufacturer = $v->MANUFACTURER; foreach ($v->PARAM[0]->VAL as $v2) {$param = $v2;} foreach ($v->PARAM[1]->VAL as $v3) {$param2 = $v3;} foreach ($v->PARAM[2]->VAL as $v4) {$param3 = $v4;} foreach ($v->PARAM[3]->VAL as $v5) {$param4 = $v5;} foreach ($v->PARAM[4]->VAL as $v6) {$param5 = $v6;} foreach ($v->PARAM[5]->VAL as $v7) {$param6 = $v7;} foreach ($v->PARAM[6]->VAL as $v8) {$param7 = $v8;} foreach ($v->PARAM[7]->VAL as $v9) {$param8 = $v9;} foreach ($v->PARAM[8]->VAL as $v10) {$param9 = $v10;} foreach ($v->PARAM[9]->VAL as $v11) {$param10 = $v11;} foreach ($v->PARAM[10]->VAL as $v12) {$param11 = $v12;} foreach ($v->PARAM[11]->VAL as $v13) {$param12 = $v13;} $qry = "INSERT into product (`product`, `ean`, `url`, `price`, `vat`, `delivery_date`, `img_url`, `img_url2`, `img_url3`, `img_url4`, `img_url5`, `category_text`, `manufacturer`, `urceni`, `cifernik`, `reminek`, `pouzdro`, `luminiscence`, `funkce`, `tvar_pouzdra`, `vodotesnost`, `rozmery`, `styl`, `typ_strojku`, `sklo`) values ('$produkt', '$ean', '$url', '$price', '$vat', '$delivery', '$img', '$img2', '$img3', '$img4', '$img5', '$cattext', '$manufacturer', '$param', '$param2', '$param3', '$param4', '$param5', '$param6', '$param7', '$param8', '$param9', '$param10', '$param11', '$param12')"; $ret=mysql_query($qry) or die (mysql_error()); } Vzorové xml <SHOPITEM><ID>3</ID> <PRODUCT>Emporio Armani Sport AR5856</PRODUCT> <URL>http://www.hodinky-365.cz/emporio-armani-sport-ar5856-x13</URL> <PRICE>3491.7299804688</PRICE> <VAT>21</VAT> <DELIVERY_DATE>0</DELIVERY_DATE> <IMGURL>http://www.hodinky-365.cz/fotky/maxi/emporio-armani-sport-ar5856_3_1.jpg</IMGURL> <IMGURL>http://www.hodinky-365.cz/fotky/maxi/emporio-armani-sport-ar5856_3_4.jpg</IMGURL> <IMGURL>http://www.hodinky-365.cz/fotky/maxi/emporio-armani-sport-ar5856_3_3.jpg</IMGURL> <IMGURL>http://www.hodinky-365.cz/fotky/maxi/emporio-armani-sport-ar5856_3_2.jpg</IMGURL> <IMGURL>http://www.hodinky-365.cz/fotky/maxi/emporio-armani-sport-ar5856_3_5.jpg</IMGURL> <CATEGORYTEXT>Emporio Armani | Emporio Armani Sport</CATEGORYTEXT> <MANUFACTURER>Emporio Armani</MANUFACTURER> <PARAM><PARAM_NAME>Určení</PARAM_NAME><VAL>Pánské</VAL></PARAM> <PARAM><PARAM_NAME>Ciferník</PARAM_NAME><VAL>analogový</VAL></PARAM> <PARAM><PARAM_NAME>Řemínek</PARAM_NAME><VAL>silikon</VAL></PARAM> <PARAM><PARAM_NAME>Pouzdro</PARAM_NAME><VAL>ocel</VAL></PARAM> <PARAM><PARAM_NAME>Luminiscence</PARAM_NAME><VAL>ručičky</VAL></PARAM> <PARAM><PARAM_NAME>Funkce</PARAM_NAME><VAL>Stopky, Datumovka</VAL></PARAM> <PARAM><PARAM_NAME>Tvar pouzdra</PARAM_NAME><VAL>kulatý</VAL></PARAM> <PARAM><PARAM_NAME>Vodotěsnost</PARAM_NAME><VAL>50M</VAL></PARAM> <PARAM><PARAM_NAME>Rozměry</PARAM_NAME><VAL>42 x 49 x 11 mm</VAL></PARAM> <PARAM><PARAM_NAME>Styl</PARAM_NAME><VAL>sportovní</VAL></PARAM> <PARAM><PARAM_NAME>Typ strojku</PARAM_NAME><VAL>QUARTZ - baterie</VAL></PARAM> <PARAM><PARAM_NAME>Sklo</PARAM_NAME><VAL>minerální</VAL></PARAM></SHOPITEM> |
||
peta Profil |
#4 · Zasláno: 15. 5. 2013, 14:04:35
Musis nejak rozlisit, ktery je ktery. Takze to bud poskladat cyklem for/forech nebo pomoci for doplnit prazdne kolonky a spojit to pomoci implode.
|
||
Tori Profil |
#5 · Zasláno: 15. 5. 2013, 15:00:43
lokix:
„z ostrého xml jsem zjistsil, že param-ů bude mít každý produkt různě což je hrůza. Podobu ovlivnit nemůžu“ V tom případě bych změnila strukturu DB a ukládala variabilní vlastnosti produktu do jiné tabulky: product_id INT (FK) name VARCHAR(50) value VARCHAR(300) Pak by to vypadalo asi takhle: foreach ($xml->SHOPITEM as $v) { // řádky 5-17 z [#3] + INSERT produktu do DB. // Pak zjistíte ID vloženého produktu $id = mysql_insert_id(); // nebo $v->ID , jestli používáte ID z importu // a vložíte další vlastnosti produktu $sql = 'INSERT INTO product_properties (product_id, name, value) VALUES '; foreach ($v->PARAM as $param) { $sql .= '('.$id.',"'.mysql_real_escape_string($param->PARAM_NAME).'","'.mysql_real_escape_string($param->VAL).'"),'; } $sql = rtrim($sql, ', '); if (!mysql_query($sql)) echo "<br>Chyba importu: ".mysql_error(); } |
||
lokix Profil |
#6 · Zasláno: 16. 5. 2013, 10:50:45
Tori:
Děkuji za další progress a návrh db se mi líbí daleko více, jen bude někde ještě něco, protože to sice uloží i do té druhé tabulky, ale jen 1 položky (name - určení, value - pánská,dámský) a pak to vypíše chybu: Chyba importu: Duplicate entry '10896' for key 'PRIMARY' samozřejmně s různými entry id. $xml = simplexml_load_file("ukazka.xml"); foreach ($xml->SHOPITEM as $v) { $produkt = htmlspecialchars($v->PRODUCT, ENT_QUOTES); $ean = $v->EAN; $url = $v->URL; $price = $v->PRICE; $vat = $v->VAT; $delivery = $v->DELIVERY_DATE; $img = $v->IMGURL; $img2 = $v->IMGURL[1]; $img3 = $v->IMGURL[2]; $img4 = $v->IMGURL[3]; $img5 = $v->IMGURL[4]; $cattext = $v->CATEGORYTEXT; $manufacturer = $v->MANUFACTURER; // $qry = "INSERT into product (`product`, `ean`, `url`, `price`, `vat`, `delivery_date`, `img_url`, `img_url2`, `img_url3`, `img_url4`, `img_url5`, `category_text`, `manufacturer`) values ('$produkt', '$ean', '$url', '$price', '$vat', '$delivery', '$img', '$img2', '$img3', '$img4', '$img5', '$cattext', '$manufacturer')"; $ret=mysql_query($qry) or die (mysql_error()); // $id = mysql_insert_id(); // nebo $v->ID , jestli používáte ID z importu // a vložíte další vlastnosti produktu $sql = 'INSERT INTO product_properties (product_id, name, value) VALUES '; foreach ($v->PARAM as $param) { $sql .= '('.$id.',"'.mysql_real_escape_string($param->PARAM_NAME).'","'.mysql_real_escape_string($param->VAL).'"),'; } $sql = rtrim($sql, ', '); if (!mysql_query($sql)) echo "<br>Chyba importu: ".mysql_error(); } |
||
juriad Profil |
lokix:
Ukaž strukturu tabulky product_properties. Vsadím své boty, že tam máš na sloupečku product_id definovaný primární klíč PRIMARY KEY místo cizího klíče REFERENCES product (product)
koukám, že nejsem sám, kdo vsází svoje boty |
||
lokix Profil |
#8 · Zasláno: 16. 5. 2013, 11:05:03
juriad:
Máš pravdu, ze zvyku jsem tam dal primary key. Jak by tedy měl správně vypadat product_id? PS. Díky za upozornění. |
||
juriad Profil |
#9 · Zasláno: 16. 5. 2013, 11:16:38
Buď přímo za definicí sloupečku místo
PRIMARY KEY napiš REFERENCES product (product)
nebo na konec definice tabulky přidej: FOREIGN KEY (product_id) REFERENCES product (product)
Viz manuál mysql: http://dev.mysql.com/doc/refman/5.5/en/create-table.html Cizí klíče nejsou nijak vyžadovány, stejně jako primární klíče, ale umožňují kontrolu integrity dat. Pokud je tabulka typu MyISAM, tak databáze cizí klíče úplně ignoruje. |
||
lokix Profil |
Moc díky za pomoc Toti a juriad, nyní to ukládá jak má.
|
||
Časová prodleva: 20 dní
|
|||
lokix Profil |
#11 · Zasláno: 5. 6. 2013, 11:12:23
Nerad otvírám znova toto téma,
ale kdyby se našel ještě jednou jeden dobrák a pomohl mi s tímto xml. Vše funguje s původním xml jak má, ale z jiným xml kde je zase jiná struktůra to nedokážu dát tak jak potřebuju. Navíc se chci zeptat jaká by byla optimálnější, lepší možnost postavit db. Vzorové xml je níže a mám problém dostat do db položky alter kde jich může být nepočítaně nebo žádná... Díky za každou radu. <alters> <alter id="7794"> <name>35</name> <code>P29019</code> <avaibility_h>0</avaibility_h> <avaibility_ks>1</avaibility_ks> <avaibility>skladem</avaibility> </alter> <alter id="7795"> <name>36</name> <code>P29020</code> <avaibility_h>0</avaibility_h> <avaibility_ks>1</avaibility_ks> <avaibility>skladem</avaibility> </alter> <alter id="7797">... Vzorové xml: <product id="21192"> <link>http://www.esho.cz/Lodicky/Damske-lodicky-cerne-na-platforme-lakovane</link><name>Dámské lodičky černé na platformě lakované</name> <code>P28951</code> <manufacturer id=""/> <pricesource>product</pricesource> <price>990</price> <price_vat>990</price_vat> <vat>0</vat> <defimg>48536</defimg> <avaibility_h>0</avaibility_h> <avaibility_ks>5</avaibility_ks> <avaibility>skladem</avaibility> <category id="1599">Lodičky</category> <categories> <category id="1599" main="1">Lodičky</category> </categories> <description> <p><strong>Popis:</strong></p> <p>Dámské lodičky na platformě lakované černé.</p> <p><em>Svršek: Syntetický materiál</em></p> <p><em>Podšívka: Syntetický materiál</em></p> <p><em>Stélka: Kombinace kůže a syntetického materiálu</em></p> <p><em>Podešev: Ostatní materiál</em></p> <p> <strong>Rozměry uvedeny níže.</strong></p></description><fulldescription><div class="popisZbozi2"> <p><strong>Velikost Délka stélky Výška podpatku Celková výška</strong><br />35 23cm 15cm 21cm<br />36 24cm 15cm 21cm<br />37 25cm 15cm 21cm<br />38 25,5cm 15cm 21cm<br />39 26cm 15cm 21cm<br />40 26,5cm 15cm 21cm<br />41 27cm 15cm 21cm</p> <p> </p> <p><strong>Výška platformy:5 cm</strong></p> </div> </fulldescription> <imgs> <img default="1" id="48536">http://www.eshop.cz/img/affil/48536-damske-lodicky-cerne-na-platforme-lakovane.jpg</img> <img id="48439">http://www.eshop.cz/img/affil/48439-damske-lodicky-cerne-na-platforme-lakovane.jpg</img> <img id="48440">http://www.eshop.cz/img/affil/48440-damske-lodicky-cerne-na-platforme-lakovane.jpg</img> </imgs> <alters> <alter id="7794"> <name>35</name> <code>P29019</code> <avaibility_h>0</avaibility_h> <avaibility_ks>1</avaibility_ks> <avaibility>skladem</avaibility> </alter> <alter id="7795"> <name>36</name> <code>P29020</code> <avaibility_h>0</avaibility_h> <avaibility_ks>1</avaibility_ks> <avaibility>skladem</avaibility> </alter> <alter id="7797"> <name>38</name> <code>P29022</code> <avaibility_h>0</avaibility_h> <avaibility_ks>2</avaibility_ks> <avaibility>skladem</avaibility> </alter> <alter id="7798"> <name>39</name> <code>P29023</code> <avaibility_h>0</avaibility_h> <avaibility_ks>1</avaibility_ks> <avaibility>skladem</avaibility> </alter> </alters> <attributes/> </product> |
||
Časová prodleva: 5 dní
|
|||
Tori Profil |
Na to by měla být další tabulka, pro varianty produktu. Ale jestli vlastnosti jednotlivých variant ukládat do této nové tabulky anebo prolinkovat z tabulky vlastností, to asi záleží na tom, jestli pracujete s jedním typem zboží nebo ne.
Např. pokud prodáváte jenom boty a neplánujete rozšiřovat sortiment o jiné zboží, může být tabulka variant produktu denormalizovaná: tab. zbozi ID | název | materiál | ... 1 | botasky dámské | svršek i vnitřek kůže | tab. varianty_zbozi ID | ID_zbozi | velikost | barva | ks_skladem ... 1 | 1 | 35 | hnědá s bílými pruhy | .. 2 | 1 | 36 | hnědá s bílými pruhy | 3 | 1 | 36 | černá s bílými pruhy | Ale pokud by to mělo být univerzálnější, pro různé druhy zboží, tak budou vlastnosti jednotlivých variant uložené jinak, např. nějak takhle: tab. zbozi ID | název .... 1 | botasky dámské | 2 | kondenzátor tantalový | tab. varianty_zbozi ID | ID_zbozi | ks_skladem 1 | 1 | 2 | 1 | 3 | 1 | 4 | 2 | 5 | 3 | tab. vlastnosti_zbozi ID | ID_varianty | název | hodnota 1 | 1 | velikost | 35 2 | 1 | barva | hnědá s bílými pruhy 3 | 1 | materiál | svršek i vnitřek kůže 4 | 2 | velikost | 36 5 | 2 | barva | hnědá s bílými pruhy 6 | 2 | materiál | svršek i vnitřek kůže 7 | 3 | velikost | 36 8 | 3 | barva | černá s bílými pruhy 9 | 3 | materiál | svršek i vnitřek kůže 10 | 4 | kapacita | 100n 11 | 4 | napětí | 100V 12 | 5 | kapacita | 220n 13 | 5 | napětí | 100V |
||
lokix Profil |
Děkuji Tori toto univerzálnější (2. řešení) je to co jsem hledal. Takto jsem tedy upravil db a jsou tam teď 3 tabulky, ale chci se zeptat jak by jste upravila ještě následné zpracování xml jako u vzorového xml? #11
|
||
Tori Profil |
#14 · Zasláno: 12. 6. 2013, 00:20:11
Tak podobně jako [#6], pseudokód:
pro každý produkt: - načti data produktu, ulož ho do DB a zjisti ID nového záznamu - pro každou variantu produktu: - připrav si začátek SQL pro ukládání vlastností: "INSERT INTO (sloupce) VALUES " - vytvoř nový záznam ve vazební tabulce (varianty_zbozi) a zjisti jeho ID - všechny potřebné informace o variantě přidej do SQL: " (1, 'velikost', 35), (1, 'cena', 990), " - z připraveného SQL odstraň čárku na konci a ulož do DB (tab. vlastnosti_zbozi) |
||
lokix Profil |
#15 · Zasláno: 12. 6. 2013, 11:48:18
Tori:
Moc děkuji tohle už snad dohromady dám,ale chci se Vás zeptat jestli máte čas a chuť si něco vydělat. Vím tady to nepatří, ale bylo by více projektů a já toho mám už více tak pokud chcete a můžete šlo by se domluvit na nějaké formě spolupráce. |
||
Časová prodleva: 11 let
|
0