Seite 1 von 1

lxml write funktioniert nicht mit pathlib

Verfasst: Mittwoch 10. April 2019, 09:30
von tz_wuerzburg
Hallo liebe Forumsmitglieder,
ich habe ein Problem mit pathlib und dem schreiben einer .xml Datei über einen durch pathlib erzeugten Pfad.

Code: Alles auswählen

import os
from pathlib import Path
from lxml import etree
import csv


datenverzeichnis = Path.cwd() / "daten"

original_datei = "original.txt"
original_datei_pfad = datenverzeichnis / original_datei

def erzeuge_xml_ospath(original_datei_pfad):
    xml_dateiname = "12345.xml"
    os_pfad = os.path.join(os.path.dirname(__file__)) + "/daten/" + xml_dateiname
    with open(original_datei_pfad, "r", encoding="utf-8") as import_datei:
        eingabe = csv.reader(import_datei, delimiter="\t")
        next(eingabe)
        root = etree.Element("root")
        name = etree.SubElement(root, "Name")
        etree.SubElement(name, "ID").text = "ID"
        et = etree.ElementTree(root)
        et.write(os_pfad, xml_declaration=True, encoding='UTF-8', pretty_print=True)


def erzeuge_xml_pathlib(original_datei_pfad, datenverzeichnis):
    xml_dateiname = "12345.xml"
    pathlib_pfad = datenverzeichnis / xml_dateiname
    with open(original_datei_pfad, "r", encoding="utf-8") as import_datei:
        eingabe = csv.reader(import_datei, delimiter="\t")
        next(eingabe)
        root = etree.Element("root")
        name = etree.SubElement(root, "Name")
        etree.SubElement(name, "ID").text = "ID"
        tree = root.getroottree()
        tree.write(pathlib_pfad, xml_declaration=True, encoding='UTF-8', pretty_print=True)


erzeuge_xml_ospath(original_datei_pfad)
erzeuge_xml_pathlib(original_datei_pfad, datenverzeichnis)
"erzeuge_xml_ospath" erstellt einen Pfad für die .xml wie folgt:
C:/Users/user/daten/12345.xml
Die Funktion läuft durch und erzeugt die Datei am richtigen Ort.

"erzeuge_xml_pathlib" erstellt einen Pfad für die .xml wie folgt:
C:\Users\user\daten\12345.xml
Die Fuktion bricht ab und bringt folgende Fehlermeldung:
TypeError: File or filename expected, got 'WindowsPath'

Noch kurz eine Frage zur lxml write Klasse. Welche ist besser zu verwenden, oder sind beide Schreibweisen ok?

Code: Alles auswählen

et = etree.ElementTree(root)
et.write(os_pfad, xml_declaration=True, encoding='UTF-8', pretty_print=True)

# oder

tree = root.getroottree()
tree.write(pathlib_pfad, xml_declaration=True, encoding='UTF-8', pretty_print=True)


Re: lxml write funktioniert nicht mit pathlib

Verfasst: Mittwoch 10. April 2019, 09:36
von __deets__
Du musst str() um das pathlib Objekt aufrufen. Leider gibt es noch diverse stellen, die nicht beides Schlucken.

Re: lxml write funktioniert nicht mit pathlib

Verfasst: Mittwoch 10. April 2019, 09:53
von Sirius3
@tz_wuerzburg: Du tust zwei verschiedene Dinge, bei `erzeuge_xml_ospath` erzeugst Du einen Pfad relativ zur Python-Datei in `erzeuge_xml_pathlib` einen Pfad relativ zum Arbeitsverzeichnis.

`erzeuge_xml_ospath` ist auch eine beschönigende Umschreibung, in Wirklichkeit stückelst Du den Pfad per + zusammen, was man auf keinen Fall machen sollte.

`eingabe` wird nirgends verwendet.

Re: lxml write funktioniert nicht mit pathlib

Verfasst: Mittwoch 10. April 2019, 10:46
von tz_wuerzburg
@__deets__
Vielen Dank, so einfach kann es manchmal sein.

@Sirius3
Die "erzeuge_xml_ospath" Funktion hatte ich auf die schnelle zusammen gebastelt um einen Vergleich zwischen pathlib und os zu schaffen.
Die "eingabe" stammt aus dem kompletten Script und wurde versehntlich, für dieses Bespiel, nicht heraus genommen.


Könnt ihr mir noch eine Empfehlung bezüglich des schreibens in die .xml geben? Welche Schreibweise ist die schönere, bzw. welche sollte für das einfache
schreiben verwendet werden?

Vielen Dank, ihr habt mir sehr geholfen.

Re: lxml write funktioniert nicht mit pathlib

Verfasst: Mittwoch 10. April 2019, 10:49
von __deets__
Die Schreibweise ist irrelevant.

Re: lxml write funktioniert nicht mit pathlib

Verfasst: Mittwoch 15. Mai 2019, 12:17
von tz_wuerzburg
Hallo zusammen,
jetzt habe ich ein ähnliches Problem mit Flask und Pathlib.

Code: Alles auswählen

print(Path.cwd() / "upload")
Ergebnis ist der Pfad in Windows Schreibweise:
C:\Users\User\Desktop\Flask_Projekt\upload

Code: Alles auswählen

from flask import Flask, render_template, request, flash, redirect, url_for
from werkzeug.utils import secure_filename
from pathlib import Path

upload_folder = Path.cwd() / "upload"

allowed_extensions = set(["txt", "csv"])

app = Flask(__name__)
app.config[upload_folder] = upload_folder

def allowed_file(filename):
    return "." in filename and \
        filename.rsplit(".", 1)[1].lower() in allowed_extensions
        
@app.route("/test", methods=["GET", "POST"])
def test():
    if request.method == "POST":
        if "file" not in request.files:
            print("Es wurde keine Datei ausgewählt")
            return redirect(request.url)
        file = request.files["file"]
        if file.filename == "":
            flash("Es wurde keine Datei ausgewählt")
            return redirect(request.url)
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(app.config[upload_folder / filename])
            return redirect(url_for("test", filename=filename))
    return render_template("test.html")

Versuche ich nun über meine Webseite eine Datei zu importieren bekomme ich folgende Fehlermeldung.
file.save(app.config[upload_folder / filename])
KeyError: WindowsPath('C:/Users/User/Desktop/Flask_Projekt/upload/file.txt')

Ich verstehe einfach nicht warum...

Re: lxml write funktioniert nicht mit pathlib

Verfasst: Mittwoch 15. Mai 2019, 12:27
von sparrow
Die Fehlermeldung sagt: Es gibt keinen Schlüssel mit dem Namen 'C:/Users/User/Desktop/Flask_Projekt/upload/file.txt' in app.config
Wahrscheinlich steht da ein bisschen viel zwischen den eckigen Klammern, die den Namen des Schlüssels enthalten sollen.

Re: lxml write funktioniert nicht mit pathlib

Verfasst: Mittwoch 15. Mai 2019, 14:32
von tz_wuerzburg

Code: Alles auswählen

file.save(str(app.config[upload_folder] / filename))
Danke!

Re: lxml write funktioniert nicht mit pathlib

Verfasst: Mittwoch 15. Mai 2019, 15:37
von Sirius3
Was soll denn überhaupt dieses app.config[upload_folder] wenn da doch nur upload_folder drinsteht.

Re: lxml write funktioniert nicht mit pathlib

Verfasst: Donnerstag 16. Mai 2019, 13:56
von tz_wuerzburg
@Sirius3
Das habe ich leider auch nicht so ganz verstanden.
In der Dokumentation wird es wie folgt angegeben:

Code: Alles auswählen

UPLOAD_FOLDER = '/path/to/the/uploads'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
Für mich ist nicht verständlich warum der Wert doppelt abgefragt wird.

Re: lxml write funktioniert nicht mit pathlib

Verfasst: Donnerstag 16. Mai 2019, 14:04
von __deets__
Das ist keine doppelte Abfrage. Vor allem aber ist der SCHLÜSSEL „UPLOAD_FOLDER“. NICHT der Pfad desselben. Was ja auch wenig Sinn macht. Wenn man den Pfad schon kennt, braucht man ihn ja nicht nachschlagen. Du machst da also etwas falsch.