XML szerkesztése

Fórumok

Sziasztok!

 

Következő problémával szenvedek egy ideje: 

- Van egy xml sablon (MOKK fizetési meghagyás).

- van egy kb. 1000 sort tartalmazó excel tábla a szükséges adatokkal.

ebből a kettőből kéne létrehoznom a kész xml dokumentumokat, kb. 1000 db.-ot (amennyiben lehetséges ubuntu használatával).

 

Első körben LO Writer körlevél funkciójával próbáltam, ami után sajnos még kézzel kellett javításokat eszközölnöm (üres cellák helyeit törölni). 

 

Van valakinek jobb ötlete a probléma megoldására, vagy maradjak ennél?

Előre is köszi az összes ötletet.

 

Üdv,

P3nész

Hozzászólások

Bármilyen programozási nyelv amiben van kész csv és xml kezelő lib/osztály.

Én valószínű megírnám programból a generálást, de lehet hogy egy sima kis script ami végigmegy a csv sorain és a template-ben a placeholdereket lecseréli az adatokra is jó lehet.

disclaimer: ha valamit beidéztem és alá írtam valamit, akkor a válaszom a beidézett szövegre vonatkozik és nem mindenféle más, random dolgokra.

Én az első Excel sor végére beszúrnám az xml-t és behelyettesíteném az értékeket. Majd lehúznám mind az 1000 sorra. Ezt csv-be exportálva már csak fel kel daraboli. Gondolom a Libre/OpenOffice is tud ilyet.

Python-ban nem tudom megírni, mert C#-ban programozok, de a

C# így néz ki

var xmlSablon = System.IO.File.ReadAllText("sablon.xml");

var csv = System.IO.File.ReadAllLines("adat.csv")
	.Skip(1) // ha van fejléce a csv-nek
	.Select(Csv.RowToObject)
	.ToList();

foreach (var row in csv)
{
	System.IO.File.WriteAllText($"{csv.IndexOf(row)}.xml",
		xmlSablon
			.Replace("[SzámOszlop]", row.SzámOszlop.ToString())
			.Replace("[DátomOszlop]", row.DátomOszlop.ToString("yyyy.MM.dd HH:mm:ss"))
			.Replace("[SzövegOszlop]", row.SzövegOszlop)
		);
}

public class Csv
{
	public int SzámOszlop { get; set; }
	public DateTime DátomOszlop { get; set; }
	public string SzövegOszlop { get; set; }

	public static Csv RowToObject(string row)
	{
		var values = row.Split(','); // szeparátor itt vessző
		return new Csv
		{
			SzámOszlop = int.Parse(values[0].Trim()),
			DátomOszlop = Convert.ToDateTime(values[1]),
			SzövegOszlop = values[2]
		};
	}
}

adat.csv

Szám,Dátum,Szöveg
1,2022.04.10 03:00,Szöveg1
2,2022.04.11 03:00,Szöveg2
3,2022.04.12 03:00,Szöveg3

sablon.xml

<?xml version="1.0" encoding="utf-8" ?>
<data>
	<d1>[SzámOszlop]</d1>
	<d2>[DátomOszlop]</d2>
	<d3>[SzövegOszlop]</d3>
</data>

Én is sablonnal csinálnám: sokkal direktebb, azaz kevésbé absztrakt mint akár az XSLT, akár az XML node-ok piszkálása programból. Egyetlen probléma, hogy eszképelni kellhet a szöveget, ha van benne kacsacsőr. Ha van erre egy segédfüggvény ami megcsinálja, akkor már egyszerű, a legnagyobb kihívás megtalálni a megfelelő eszképelő függvényt, illetve biztosítani, hogy sehol ne maradjon ki, ahol szükség van rá. De ha szerencséd van nem is kell eszképelni csak behelyettesíteni a szöveget és kész.

Az XSLT pont erre valo (XML manipulalasra). De amugy most Pythonban irnam meg, mert epp az van a fejemben.

A strange game. The only winning move is not to play. How about a nice game of chess?

Én is XSLT-re gondoltam először, de egyfelől csak a fordítottját csináltam (XML-ből csv generálása), másfelől több, mint 20 éve volt, szóval nem tudnám most megírni. A másik kettő, amit írtam, az meg menne viszonylag egyszerűen és hamar.

XSLT-ben hogyan veszed ki a következő mezőt a csv-ből?

disclaimer: ha valamit beidéztem és alá írtam valamit, akkor a válaszom a beidézett szövegre vonatkozik és nem mindenféle más, random dolgokra.

Ahogy irtam is, most pythonoznek, ha meg kene oldanom. Egyebkent ha mondjuk tab separated a csv (vagy nincsenek benne hulye karakterek), nem nagy dolog bash-ben sem feldolgozni, az xml reszet meg az xsltproc megoldja (--param adja at a plusz parametert).

Igazabol arra akartam csak felhivni a figyelmet, hogy az XML nem csak a fileformatumbol all, hanem van mellette validator, feldolgozo, meg ezeknek a template-jei (szinten XML formatummal). Tisztara ugy nez ki, mint ha valakik leultek volna, hogy megtervezzek.

A strange game. The only winning move is not to play. How about a nice game of chess?

Sziasztok!

 

Nagyon köszi az ötleteket. Sajnos programozni nem tudok ilyen szinten, így azt hiszem marad a LO Writer körlevél funkció, Az utólagos kézimunkára kell valamit még kitalálnom. Annyi talán még megy a programozásból :-)

 

Még egyszer köszi az ötleteket és a segítséget,

P3nész

Python amúgy is tervbe van véve, szóval biztos, hogy hosszabb távon az a megoldás, de most hétfőre kell megoldanom, így 0-ról nem mennék neki.

Köszi a buzdítást :-)

P3nész

Sőt, python 3.6-tól kezdve van f-string amibe {}-vel lehet string interpolációt csinálni.

pentike@T440s:~/sandbox/py$ cat test.csv 
nev;cim
pentike;bp
pentike@T440s:~/sandbox/py$ cat csv2xml.py 
import csv

with open('test.csv', 'r') as csvfile:
    csvr = csv.DictReader(csvfile, delimiter=';', quotechar='"')
    for record in csvr:
        print(f'''<doksi>
    <nev>{record["nev"]}</nev>
    <cim>{record["cim"]}</cim>
</doksi>''')
pentike@T440s:~/sandbox/py$ python3 csv2xml.py 
<doksi>
    <nev>pentike</nev>
    <cim>bp</cim>
</doksi>

Én is a mostmár a Python-nál maradék, bár előtte csináltam C#-ban is hasonlót. Python script pedig fut LO alatt!!! XSLT-t utoljára az egyetemen.

Szerkesztve: 2022. 08. 13., szo – 17:07

Bash, soronkent vegig a csv allomanyon, benne egy valtozo az xml eleje, aztan sed vagy awk az aktualis sor pontos formazasahoz, amit beletolsz egy valtozoba, aztan egy ujabb valtozo az xml vege, a kimeneti file valtozo is a sor egyik mezejetol fugg, aztan egy echo a harom valtozo osszefuzesevel, atiranyitva a negyedik valtozo altal tarolt nevu fileba, igy a futas utan lesz 1000 allomanyod. Nem tul elegans, ellenben egyszeru. Az echo elott mondjuk en tennek nehany ifet, ami jelez, ha rossz adat van, vagy nincs adat a sorban, pl. ures file nevbe nem jo otlet barmit is beleiranyitani... :-)

Olvasom itt a mindenféle bonyolultabbnál bonyolultabbnak tűnő megoldást. Nem tartom magam nagy PHP-rajongónak, de nem azzal lenne a legegyszerűbb, bele a mezőket az XML-be <?= ?> tagben hivatkozva?