XML-Problem: XML zu CSV

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
PhantomWorks
User
Beiträge: 18
Registriert: Samstag 25. April 2009, 11:11

Hallo!

Vielen Dank für Eure Antworten! Ich hatte vergangenes Wochenende ZEit und bin kurz vor der Lösung.

Es gibt nur noch ein einziges Problem:

Wenn ich die Elemente der CSV-Datei die ich in Variablen gespeichert habe mit dem CSV-Writer über writerow schreiben will passiert folgendes: Es steht in jedem Feld nur ein einziger Buchstabe, d.h. ein Wort mit 10 bestehend aus 10 Buchstaben erstreckt sich momentan über 10 Spalten.

Habe schon hin und her probiert, bin jedoch noch auf keinen grünen Zweig gekommen.

Hat einer Rat an was das liegen kann?
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Dann solltest du mal den Code zeigen, der die CSV-Datei schreibt.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Ich rate mal: du übergibst die Zeile nicht als Tupel sondern irgendwie als String?
Das Leben ist wie ein Tennisball.
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

strings sind tupel von zeichen, daher das seltsame verhalten...

Code: Alles auswählen

In [23]: w.writerow("hallo")

In [24]: w.writerow( ("hallo",) )

In [25]: print o.getvalue()
h,a,l,l,o
hallo
http://www.kinderpornos.info
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Du meinst, Strings sind Sequenzen aus Strings ;)
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

wenn schon, dann (immutable) sequenz von chars und escapeseqs (mit evtl. prefix)

Code: Alles auswählen

stringliteral   ::=  [stringprefix](shortstring | longstring)
stringprefix    ::=  "r" | "u" | "ur" | "R" | "U" | "UR" | "Ur" | "uR"
shortstring     ::=  "'" shortstringitem* "'" | '"' shortstringitem* '"'
longstring      ::=  "'''" longstringitem* "'''"
                     | '"""' longstringitem* '"""'
shortstringitem ::=  shortstringchar | escapeseq
longstringitem  ::=  longstringchar | escapeseq
shortstringchar ::=  <any source character except "\" or newline or the quote>
longstringchar  ::=  <any source character except "\">
escapeseq       ::=  "\" <any ASCII character>
du hast angefangen :P
http://www.kinderpornos.info
BlackJack

@Dill: Nein, denn es gibt in Python keine `char`\s [1]_. Die Beschreibung von Zeichenkettenliteralen im Quelltext und die Eigenschaften von `str`-Objekten sind zwei verschiedene paar Schuhe.

Zeichenketten sind eine ("immutable") Sequenz von Zeichenketten der Länge 1, ist denke ich eine treffende Beschreibung, die das Phänomen erklärt.

.. [1] Jaja, ich weiss, es gibt `ctypes.c_char`.
problembär

PhantomWorks hat geschrieben:Vielen Dank für Eure Antworten! Ich hatte vergangenes Wochenende ZEit und bin kurz vor der Lösung.
Schön. Und wie jetzt, mit minidom oder lxml/etree?
(Bei letzterem bin ich raus.)

Gruß
PhantomWorks
User
Beiträge: 18
Registriert: Samstag 25. April 2009, 11:11

@problembär: Ich verwende jetzt lxml/etree. Ich habe zwar auch einen Versuch mit minidom gestartet, diesen jedoch bald wieder verworfen.

@all:
Ich habe mir nun die csv.DictWriter Funktion angesehen
csv.DictWriter(csvfile, fieldnames[, restval=''[, extrasaction='raise'[, dialect='excel'[, *args, **kwds]]]])
als auch das was dahinter steckt

Code: Alles auswählen

class DictWriter:
    def __init__(self, f, fieldnames, restval="", extrasaction="raise",
                 dialect="excel", *args, **kwds):
        self.fieldnames = fieldnames    # list of keys for the dict
        self.restval = restval          # for writing short dicts
        if extrasaction.lower() not in ("raise", "ignore"):
            raise ValueError, \
                  ("extrasaction (%s) must be 'raise' or 'ignore'" %
                   extrasaction)
        self.extrasaction = extrasaction
        self.writer = writer(f, dialect, *args, **kwds)
        self.writer.writerow(fieldnames)

    def _dict_to_list(self, rowdict):
        if self.extrasaction == "raise":
            for k in rowdict.keys():
                if k not in self.fieldnames:
                    raise ValueError, "dict contains fields not in fieldnames"
        return [rowdict.get(key, self.restval) for key in self.fieldnames]

    def writerow(self, rowdict):
        return self.writer.writerow(self._dict_to_list(rowdict))

    def writerows(self, rowdicts):
        rows = []
        for rowdict in rowdicts:
            rows.append(self._dict_to_list(rowdict))
        return self.writer.writerows(rows)
Mein Code:

Code: Alles auswählen

fieldnames=['A1','A2', 'A3', 'A4', 'A5']
csv.DictWriter((csv_file, 'w'), fieldnames, restval="", extrasaction="raise", dialect="excel", *args, **kwds)
Ich bekomme folgenden Error:
File "C:\Python26\lib\csv.py", line 133, in __init__
self.writer = writer(f, dialect, *args, **kwds)
TypeError: argument 1 must have a "write" method
Wozu brauche ich dieses *args, **kwds? ich habe schon hier im Forum danach gesucht und auch etwas gefunden doch meiner Meinung nach ist dieses für meinen Anwendungsfall nicht notwendig.

Ich habe inzwischen eine Liste erzeugt aus allen Merkmalen, wobei jedes Merkmal (eindeutig durch die ID identifiziert) ein Dictionary darstellt. Ziel ist es nun die Dictionaries anhand der Fieldnames die ich mit den Schlüsseln des Dicts gemappt habe (also z.B. entspricht der Schlüssel Merkmal ID --> A1, Name --> A2 usw.), zeilenweise in die CSV zu schreiben, sodass letztendlich jedes einzelne Dict der Liste eine Zeile der CSV darstellt.

Viele Grüße
BlackJack

@PhantomWorks: In der Doku zu csv.DictWriter kannst Du nachlesen, dass als erstes Argument eine Datei ewartet wird. So wie's aussieht übergibst Du aber ein Tupel mit, keine Ahnung was `csv_file` ist, und einer Zeichenkette. Und so ein Tupel hat im Gegensatz zu einer Datei keine `write()`-Methode.

Wieso übergibst Du die ganzen Argumente mit den gleichen Werten wie sie sowieso schon vorbelegt sind? Was ist an ``*args`` und ``**kwds`` gebunden und *warum*?

Vielleicht magst Du mal das Tutorial zum Thema “Defining functions“ durcharbeiten.
Antworten