xml to csv

XML-ben van némi adat, amit szeretnék parancssorból automatizáltan feldolgozni, és bizonyos adatokat CSV-be írni. Mivel XML-t sose kellett komolyabban turkálnom, azt se tudom milyen eszközök jöhetnek szóba. Ha van használható ötleted némi példakóddal és megosztod, azt megköszönöm. Környezet: Ubuntu.

Hozzászólások


<?php
$array = json_decode(json_encode( simplexml_load_string(file_get_contents("test.xml"), "SimpleXMLElement", LIBXML_NOCDATA)),true);
var_dump($array);

És kiszeded a tömbből ami kell (persze lehet szabályosan is :))

Ha test.xml a bemenő és test.csv a kimenő adat és a node1 alatti node2 alatti elemeket akarod exportálni, akkor PowerShell-lel:


$Data = [Xml] (Get-Content test.xml)
$Data.node1.node2 | Export-Csv test.csv -NoTypeInformation

Üdv,
Marci

Példa PowerShellre:

test.xml:

<?xml version="1.0"?>
<database>
  <record>
    <DisplayName>Garvin, Fred</DisplayName>
    <Mail>fred.garvin@contoso.com</Mail>
  </record>
  <record>
    <DisplayName>Flynn, Phineas</DisplayName>
    <Mail>phineas.flynn@contoso.com</Mail>
  </record>
  <record>
    <DisplayName>Bates, Gil</DisplayName>
    <Mail>gil.bates@contoso.com</Mail>
  </record>
</database>

Legyen a feladat, hogy ebből az XML-ből a Mail és a DisplayName tulajdonságokat tegyük a test.csv-be.

Ekkor a script ennyi:

$Data = [Xml] (Get-Content test.xml)
$Data.database.record | Select-Object -Property Mail,DisplayName | Export-Csv test.csv -NoTypeInformation

Eredmény:

"Mail","DisplayName"
"fred.garvin@contoso.com","Garvin, Fred"
"phineas.flynn@contoso.com","Flynn, Phineas"
"gil.bates@contoso.com","Bates, Gil"

Üdv,
Marci

Marci, te olyan vagy, mint az ürge a viccben, akinek kört, háromszöget és téglalapot mutogatnak. Neked mindenről *az* jut eszedbe. (Csak neked ez nem a szex, hanem a Powershell.) Mindenesetre értékelem az igyekezetet, sajnos nulla PS tudással nem tudtam a kódodat olyanra hozni, hogy megkapjam a kívánt eredményt. (BTW, most kell az a Select-Object, vagy nem?)

Egyelőre még keresgélek, de leginkább azért, mert noha elvben az xmlstarlet (és a linkelt példa) akár még jó is lehet, (vagy egy xml2 nevű csomag, amiben van egy direkt 2csv nevű parancs) - épp nem tudom letölteni ezeket a csomagokat, így nem biztos, hogy azok megfelelőek.

=====
tl;dr
Egy-két mondatban leírnátok, hogy lehet ellopni egy bitcoin-t?

"Neked mindenről *az* jut eszedbe." -- Van benne valami! :)

Akár itt, akár privátban küldj példát a file-ból meg azt, hogy milyen formára kéne hozni.
A Select-Object akkor kell, ha más sorrendben akarod a mezőket kiírni, mint amilyen sorrendben az input tartalmazta, vagy ha nem akarsz minden mezőt a kimenetben látni.

Üdv,
Marci

XMLStarlet sel opciója... pl. így: http://www.joyofdata.de/blog/transforming-xml-document-into-csv-using-x…

Szerk.: egyébként nem tökéletes, mert a CSV meglehetősen bonyolult formátum és sok ponton megborulhat... a fenti PHP-s ötlet, még egy fputcsv-vel kiegészítve, hogy helyes CSV kimenetet kapj. Persze ha biztosan nincs több soros érték, szöveghatároló, szöveghatárolt értékben előforduló szöveghatáró stb. az adatokban, akkor az xmlstarlet-es is működik.

BlackY
--
"en is amikor bejovok dolgozni, nem egy pc-t [..] kapcsolok be, hanem a mainframe-et..." (sj)

Visszakérdezek: esetleg AWK-al való megoldás?

G.
============================================
"Share what you know. Learn what you don't."

Python3-mal.
Lehetne kevesebb sorral is, de akkor kevésbé olvasható.
Kérdés: hogyan kell BBcode-dal xml-fájlt betenni? Csak így sikerült, hogy a '<' után szóközt hagytam.


#!/usr/bin/env python3
#-*- coding:utf-8 -*-

import sys
import xml.etree.ElementTree as et

sep=","
#sep=";"
fields= ("field1","field2")

if len(sys.argv)!=2:
	print("Missing file name.")
	sys.exit(1)

tree = et.parse(sys.argv[1])
root = tree.getroot()
fout= open(sys.argv[1]+".csv","w+")

for rec in root.findall("record"):
	d={ child.tag:child.text for child in rec if child.tag in fields }
	l= [ text for (tag,text) in sorted(d.items()) ]
	fout.write( sep.join(l)+"\n")
	
fout.close()

Az input:

<?xml version="1.0"?>
< database>
  < record>
    < field1>value1< /field1>
    < field2>value2< /field2>
  < /record>
  < record>
    < field2>value4< /field2>
    < field1>value3< /field1>
    < kakukk>madár< /kakukk>
  < /record>
  < record>
    < field2>value6< /field2>
    < field1>value5< /field1>
  < /record>
< /database>

--
eutlantis