XML-ből CSV

Fórumok

Sziasztok!

Már napok óta szívok az alábbi problémával:

Van egy XML fájlom. Itt tekinthetitek meg: http://pastebin.com/02brCLhk

Ez egy árgépes xml fájl (helyesbítek: ezt tölti le és eszi meg az árgép), egyetlen termékéről szóló rész, de ezt szorozzátok be úgy 5000 termékkel. A fájlméret meglehetősen vaskosnak mondható: 2 MB körüli.

Ebből kellene nekem faragnom egy CSV fájlt, de nem olyan egyszerű ám ez!
Próbálkoztam XML2CSV konverterekkel meg online konverterekkel, de egyik se ette meg, mondván parse error.
A dolgot nehezíti, hogy akad a description-ben ; (azaz pontosvessző) is.

Mi a megoldás?
Bármilyen ötletre vevő vagyok (Googleztam is már, de kevés sikerrel jártam.

Köszi előre is a segítséget.

Hozzászólások

Az ÁrGép-esek szívesen segítenek, gondolom: keresd meg őket.

Üdv,
Marci

Itt az ideje nekiállni programozni vagy regexp-es cserefunkciót tartalmazó szövegszerkesztővel nekiesni. :)

Láttam már ilyeneket. Aztán valahogy mindig volt valami gondja, ami miatt patkolni kellett. Miután ki lett baszva az egész a picsába és egy rendes XML olvasására készített osztály lett beállítva, hirtelen megszűntek a nyűgök.

Amikor meg hibás XML-t kaptam, valahogy mindig kiderült, hogy valami turpisság van a túloldalt.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Nem tudom ki és miért akar regexppel szopni mikor a fenti feladat kb. ennyi:

var xdoc = XDocument.Load("basz.xml");
foreach (var xelem in xdoc.Element("channel").Elements("item"))
{
  randomCsvWriter.Write(new string[] {
    xelem.Element("manufacturer_name").Value,
    xelem.Element("product_ski").Value,
    ...
  });
}

Ezen nincs mit elbaszni. Regexpen ezer dolgot lehet. Arról nem beszélve, hogy ezer+1 olyan dolgo van az XML-ben, amit nem biztos, hogy le fogsz kezelni egy regexp kifejezésben, ellenben egy regexp parser le fogja.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

A lényeg: amíg az adat nincs a kezembe, addig NINCS.
Magyarázat: (Közben megláttam ezt a hozzászólásodat is: http://hup.hu/cikkek/20150107/sokszor_ugy_erzem_az_informatikaval_szakm… )
Az előbbi hozzászólásomat kissé továbbfejlesztem. Az xml elég precíz formátum - lehetne. Csak adatokhoz nem értők is használják.

Konkrét példa:
- A mező neve: irányítószám
- Érvényes: numerikus 1-5 karakter (Segítek: Magyarországról van szó!)

Mivel még fejlesztés alatt volt, a telefon nevű tool-hoz nyúltam. Elmagyaráztam a formátum föltalálójának (külső cég, csak ezért alkalmazva), hogy kis országunkban az 1, 2, 3 és 5 jegyű irányítószám nem van. Viszont kellene 0 hossz - már ha megegyezünk - mert olyan meg van, hogy nincs. Ti. irányítószám ;)

Szóval, logikád szerint az az informatikus, aki jól használja a jól bevált eszközöket, de fingja sincs az eszközök által kezelt adatokról?

Helyette mondjuk inkább, hogy a jól konvertálható adatok a továbbiakban nagyobb valószínűséggel dolgozhatók fel helyesen.

Bezzeg a topic folyik, minden IT guru tudja melyik a legjobb tool! Nem szánalmas?

A nem olyan jól konvertálható adatok is könnyebben dolgozhatók fel egy, a nem olyan jól konvertálható adatformára kihegyezett eszközzel.

(Írom ezt a triviát úgy, hogy direkt mazochizmusból hajdan mentettem rekordokat tönkretett dbf-ből (klasszikus módon * commanderben megnyitották szerkesztésre, aztán gyorsan rá is mentettek, kidobva a fejléclezáró karakterpárt) awk+dd használatával, aztán ugyanarra a problémára összegányoltam C-ben egy egylövetűt. Mindkét esetben ismernem kellett az adatszerkezetet, de az utóbbit nem csak futtatni, hanem megírni is harmadannyi volt. Ma meg ugyanerre használnám valamelyik oszlopszerkesztést tudó editort, fejben futtatva az oszloptördelés algoritmusát.)

Ez roppant érdekes, de csak absztrakció. A végén elég sok ostobaságnak tűnő dologgal, miszerint a cpu architektúrát veti össze az absztrakciót megvalósító programnyelvek tulajdonságaíval.
Részemről hiányolom egy lsi elemekből megépített bipoláris processzoron megvalósított végesállapotú géppel kivitelezett xml feldolgozás leírását. Bár ez napjainkban nem mondható tipikusnak. :)
Egy automata megvalósítható funkcionális, imperatív, kevert és egyéb programozási technikával. Sőt gépi kódtól kezdve egészen az sql-ig bármivel.

A "végtelen állapotú automa" = kis irónia azt jelenti, hogy aki ilyen marhaságot ír a véges állapotú gépről (alias automata), annak vajmi kevés fogalma lehet annak mibenlétéről.

Szóval hatékonyabb lenne egy értelmes magyar mondat segítségével kifejezni gondolataidat: alany, állítmány, tárgy stb.

"A fájlméret meglehetősen vaskosnak mondható: 2 MB körüli."

Miért is? 2 Mb-s XML az semmi.

http://msdn.microsoft.com/en-us/library/system.xml.linq.xdocument%28v=v…

http://php.net/manual/en/class.domdocument.php

Nagyjából 10-15 sornyi kódból el lehet intézni ezt .NET-ben vagy PHP-ban. (Vagy akármi másban, ami nyújt valami hasonló osztályt.)

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Igen, csak az ilyen egyszerű konvertálásokra simán nyitok egy LinQPad-ot és ott megcsinálom, aztán el is felejtem, hogy feladat volt. Mindenféle osztálygenerálgatás nélkül. :)

Amúgy .NET-ben is van valami XMl serializáció.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Ezt még hozzá akartam írni:

"A dolgot nehezíti, hogy akad a description-ben ; (azaz pontosvessző) is."

Ismerni kellene a CSV-t is (avagy, miért nem lehet regexppel feldolgozni azt sem, illetve, hogy miért nem igaz az, hogy egy sor = egy rekord.) Idézőjelek közé kell tenni és TADA. (Persze, idézőjeleket is escapelni kell dupla idézőjellé).

De erre meg:

http://php.net/manual/en/function.fputcsv.php

Nem kell újra feltalálni a spanyolviaszt, hanem használni kell a meglévő, jól kidolgozott függvényeket, osztálykönyvtárakat.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

ezt nekem pl az excel tök használhatóan megnyitja.

Udv,

En hasonlo cipoben jartam, akkor php dolgozta fel az xml fileokat, es xlsx-be convertaltam at oket phpexcel segitsegevel, mivel a CSV szetesik ha "newline" karakterrel talalkozik. (illetve parallel egy adatbazisba is el kellet menteni az xml tartalmat, ami siman ment php-bol)

Bocs ha nem tudtam magam rendesen kifejezni.

Talakoztam mar sok olyan csv file-al amit adatbazisbol generaltak (SAP MDM), es ha az adott mezoben olyan stringet taroltak amiben newline/sortores/hogyishivjak volt akkor a csv file-t excelben megnyitva ezen a bizonyos ponton a sorok elcsusztak.

Szoval nem a CSV esik szét hanem a file excelben/openoffice-ban valo megjelenitese valik feletteb bosszantova. Foleg ha par szazezer sok kozul van huszon egynehany ahol ez elofordul.

ez igy nem teljesen igaz, korrektul escapel, csak a 3rd party alkalmazas ami feldolgozza a csv-t egy fos es nem tudja normalisan ertelmezni.

De visszaterve az eredeti temahoz itt egy egyszeru, pelda simplexml-el.


<?php
$file='teszt.xml';

$xml = simplexml_load_file($file, 'SimpleXMLElement',LIBXML_NOCDATA);

$csvarray=array();
foreach($xml->item as $item){
$csvarray[]=array(
$item->manufacturer_name,
$item->product_sku,
$item->product_name,
trim(preg_replace('/\s+/', ' ', $item->product_desc)), // sortores kiszedese
$item->product_price,
$item->product_availability,
$item->picture_url,
$item->price_with_tax,
);

}

$fp = fopen('cav_file.csv', 'w');

$delimiter = chr(9); //tab
$enclosure = '"';

foreach ($csvarray as $fields) {
fputcsv($fp, $fields, $delimiter, $enclosure);
}

fclose($fp);
unset($csvarray);

echo "vege";

A parse error nem véletlen. Amit posztoltál, az a rész hibátlan. Keresd meg a parse error okát, és szüntesd meg. Ha megvan, ez is működik, pl.:


sed -i ':a;N;$!ba;s/\n/\t/g' teszt.xml

xml2 < teszt.xml > teszt.txt

2csv item manufacturer_name product_name product_desc product_price product_availability picture_url price_with_tax < teszt.txt > teszt.csv

Direkt szedtem 3 sorra, hogy lássad, mit csinál lépésről lépésre.

Kérdés: ha már hozzáférsz a szerverhez, nem egyszerűbb egyenesen az adatbázisból kiolvasni, ami neked kell, és egyből csv-t írni?
Update: ha jól látom, virtuemart motor van alatta, ajánlom átnézésre: http://www.csvimproved.com/en/support/204-export/virtuemart/842-export-…
--
Coding for fun. ;)

Nem jött össze. :(

A CSV-ből ennyi marad (persze, maga a fájl tartalmazza a 4000 terméket):

Egy sort idézek:

KORG,KORG Pa-50SD ajándék puhatokkal, {youtube}O9Hd4CwxtTE{/youtube}

,145669.00000,,http://www.csutorhangszer.hu/components/com_virtuemart/shop_image/produ…

A gond az, hogy maga a termék tartalmazza a többi leírást is, és az nem kerül bele, csak a Youtube link.

Mi a gond?

--
-- GKPortál Blog
Tégy Jót!
Legyen neked is Dropbox tárhelyed! :)

itt az XSL, modositsd kedvedre: http://pastebin.com/JS7VRv8x

meghivas, hasznalat:


asd@locutus:/tmp$ xmlstarlet tr tmp.xsl tmp.xml
KORG;korg_pa50sd;KORG Pa-50SD ajándék puhatokkal;145669.00000;;http://www.csutorhangszer.hu/components/com_virtuemart/shop_image/product/KORG_Pa_50_4a0d7361b9457.jpg;185000;
asd@locutus:/tmp$

Latom az egyetlen epeszu megoldast meg senki nem nezte meg :)

PHP alatt is mukodik: http://php.net/manual/en/xsl.examples.php

--

Az Extensible Stylesheet Language Transformations (röviden XSLT) XML-alapú fájlformátum illetve a hozzá tartozó feldolgozó rendszer. Az XSLT feldolgozót XML dokumentumok más, ember által könnyebben értelmezhető formátumra alakításához használják. A konverzió során az eredeti file megmarad, s annak tartalma alapján létrejön a célformátumban egy új fájl.[1]

A keletkező dokumentum formátuma lehet többek között XML, HTML, XHTML, PDF vagy normál szöveg.[2] Az XSLT-t gyakran használják különböző sémájú XML dokumentumok közötti konverzióra, dinamikus weboldalak létrehozására és PDF dokumentumok generálására.

Ez így igaz, viszont amit nem értenek, abban nem sokat vezet előre egy konkrét feladattal kapcsolatban egy odavágott wiki link, amely kb. mindazt tartalmazza, amit a szóban forgó dologról az is tudja, aki nem érti, viszont többet se nagyon taglal.

Ennyi erővel az IBM DB2 linkjét is be lehet dobni válaszként - mert tényleg az - csak érteni kell hozzá.

Nézd meg a Pentaho Spoon nevü eszközét, az ilyesféle adattranszformációkra való. Az ezzel előállított KTR fájt utána akár automatizáltan is futtathatod.

--
Pásztor János
Üzemeltető Macik

Kicsit useless comment, elmélet:
http://en.wikipedia.org/wiki/Delimiter-separated_values
Sok helyen nem veszik a fáradságot a mezők kezdetének és végének jelölésére (field enclose). Ha ez megtörténne, akkor row delimiterek és a field separatorok használata az értékben nem törné el a CSV-t. Ezt nagyon megtanultam, amikor Infobrightot etettünk CSV-vel.

-----------
"Pontban 0:00-kor nem nagyon szoktak véletlen dolgok történni"

Telekom szektorban is szeretik a CSV-t es szopunk is vele. A rajtad emlitetteken kivul tudom emliteni a struktura teljes hianyat (1 dimenzios adatszerkezet), a tartalom kodolasanak egyeb fogyatekossagait (ujsor karakter, idezojel), valamint a valtoztatasok (change management) bonyolultsagat.

Amugy BER kodolason (http://en.wikipedia.org/wiki/X.690#BER_encoding) semmi nem fog ki ;)

Na az olyan embert kell eltiltani az IT-tól :)
Mi anno az Inforbright-ba töltendő adatokat MySQL-ből CSV-ben nyertük ki (LOAD DATA INTO ... INFILE ...) és azt adtuk oda neki. Mentségemre szóljon, hogy a community edition-nél nem volt más lehetőség.

-----------
"Pontban 0:00-kor nem nagyon szoktak véletlen dolgok történni"

A titok inkább abban rejlik, hogy tudni kell nem használni.

Lassan jobban árulkodik az ember előéletéről konfig-/(meta)adatkezelése, mint a szakmai önéletrajz.

Aki ha belepusztul is, struktúrálatlan szövegfájlokat használ, kulcs-érték párokkal, régi, junikszónli motoros.
Ha ugyanezt teszi bármi áron úgy, hogy a kulcsok pontokat is tartalmaznak, belenőtt a java propertykbe.
Aki nem-delimitált ASCII-t dob a környezetbe, valószínűleg az ősz szakállával takarózik, a munkahelyén csak egy nála idősebb fordul elő: a gép, amit kezel.
Akinek a horizontját a CSV jelenti, időnként beír a HUP-ra, a linuxfikázó topicokba.
A mindent JSON-ozók az ls/dir parancsot is úgy kezdik, hogy <?.
Aki pedig az XML-t nem hajlandó soha másra cserélni, az nagyon modern, nagyon enterprájz, és nagyon fiatal.

Elnézést, ha kihagytam valakit!

Ugye ezért nem fizetnek egy vasat se?

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Ugyanez C#-ban, 8 perc:

http://shared.muportal.hu/csvplz2.txt

(Szerk.: Oké, Linqpadban írtam, de kb. ugyanezt kell a VS-be is beírni. Viszont Linqpadból ingyenes van, szóval ott még auto complete sincs.)

(Szerk. 2: Elfelejtettem említeni, hogy itt írtam egy Escape() metódust, mert nem volt humorom kikeresnem, hogy .NET alatt mivel írunk CSV-t szabályosan. Házi feladat.)

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

LinQPad azért másra van. Az csak ilyen firkapad, míg a VS egy rendes IDE. (Mellesleg ez a komplexitású program egy notepad(++)-al megírható és konzolból csc-vel lefordíthatható, ami úgy is ott van minden .NET telepítésben...)

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Na, számomra ez az igazi bónusz, PowerShell:

Select-Xml -Path "src.xml" -XPath "/channel/item" | Select-Object -ExpandProperty Node  | Export-Csv -Path "ps.csv"

Egy hátránya van, nem tudom, hogy a CDATA-s részt hogy lehet vele kibontani, ezt is most ollóztam össze googleből, nem ismerem a PowerShellt egyáltalán.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™