Zeilen- und Spaltennummer mit ElementTree

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.
Antworten
Benutzeravatar
Jerry
User
Beiträge: 13
Registriert: Freitag 29. Oktober 2010, 15:00

Moin,

Ich schreibe grade an einem kleinen Programm, in dem unter anderem eine xml Datei ausgewertet werden muss. Beim parsen möchte ich gerne dem User eine Rückmeldung geben, falls irgendwo Mist drin steht, obwohl es sich um syntaktisch korrektes Xml handelt. Ein kleines Beispiel:

Code: Alles auswählen

<group name="General">
    <entry name="option1" type="String">
         <default>Default String</default>
    <entry name="option2" type="Int">
        <default>zwölf</default> <--HIER
    </entry>
</group>
Wie kann ich nun beim parsen (vorzugsweise mit ElementTree) die genaue Zeilen- und optimalerweise auch die Spaltenummer rauskriegen?

Gruß, Dennis
Nur weil ich paranoid bin, heisst das noch lange nicht, dass ich nicht verfolgt werde!
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

In diesem Falle würde ich mittels XML Schema eine Grammatik für das XML Format spezifizieren (oder mit Relax, würde mich auch mal interessieren) und dann den Validator von lxml darauf loslassen. Damit erhältst Du eine schöne Fehlermeldung iirc inkl. Zeilen und Spaltenummer.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@Jerry: `lxml.etree` kennt auf `Element`-Objekten ein `sourceline`-Attribut:

Code: Alles auswählen

In [56]: doc.xpath('entry[@name="option2"]/default')[0].sourceline
Out[56]: 5
Benutzeravatar
Jerry
User
Beiträge: 13
Registriert: Freitag 29. Oktober 2010, 15:00

@Hyperion
Ich hätte vielleicht erwähnen sollen, dass es bereits ein Xml Schema gibt^^ Aber wie du an dem Beispiel sehen kannst, ändert sich ja der erlaubte Wert des default-Elements in Bezug auf das type-Attribut des entry-Elements(und da hörts leider noch nicht auf). Ich bin allerdings noch nicht dahinter gekommen wie ich das im Schema definieren soll bzw. ob das so überhaupt möglich ist...

@BlackJack
Danke, dass wusste ich noch nicht. Aber (irgendwas ist ja immer -.-), ich zögere da ein bisschen, lxml zu verwenden (obwohl es mir das Leben auch an anderer Stelle einfacher machen würde!). Mein Programm kann nämlich nicht nur als eigenständige Anwendung laufen, sondern auch in anderen Anwendungen genutzt werden (PyKDE-Anwendungen, ausschließlich), daher möchte ich nur sehr ungern weitere Abhängigkeiten haben. Ich könnte natürlich die Qt eigenen Klassen benutzen (die sind ja gegeben), aber das ganze Geraffel mit QString und QStringRef ist einfach nicht schön, ich bevorzuge da doch eine native Python Lösung, geht das nicht irgendwie mit dem von Python mitgelieferten ElementTree Modul? Ich mag die ElementTree-Api :cry:

Vielen Dank für die Antworten!
Nur weil ich paranoid bin, heisst das noch lange nicht, dass ich nicht verfolgt werde!
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ach so... hm... da könnte man sich natürlich fragen, wieso das so sein muss und ob das nicht schlechtes Design des XML-Formates ist :mrgreen:
Würdest Du nicht "stumpf" <entry>-Tags nutzen, sondern z.B. <entryInt>, <entryString> usw., so könntest Du das via XML Schema rausbekommen. Andere Standardattribute können die entries ja ruhig haben. Oder man führt eine neue Ebene unterhalb von <entry> ein, die dann den folgenden Datentypen einschränkt.

Aber bevor ich lange philosophiere, vielleicht ist das ja auch vorgegeben und Du musst jetzt damit klarkommen :-D
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@Jerry: Ich weiss nicht ob ich den letzten Satz vor dem "Frowney" richtig interpretiere, aber Du weisst, dass die API von `lxml.etree` eine etwas erweiterte `ElementTree`-API ist!?
lunar

@Hyperion: Wenn das schlechtes Design wäre, dann wäre XSD selbst schlecht entworfen. Es ist aber halt nun mal so, dass man bestimmte Bedingungen (e.g. Typkorrektheit) grammatikalisch nicht prüfen kann, und XSD ist eben nur ein Grammatik-Spezifikation. Ich würde im Gegenteil eher "entryInt", "entryString", usw. für schlechtes Design halten, denn das ist weder flexibel, noch einfach zu verarbeiten, und zudem aufgeblasen.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

lunar hat geschrieben:@Hyperion: Wenn das schlechtes Design wäre, dann wäre XSD selbst schlecht entworfen. Es ist aber halt nun mal so, dass man bestimmte Bedingungen (e.g. Typkorrektheit) grammatikalisch nicht prüfen kann, und XSD ist eben nur ein Grammatik-Spezifikation.
Naja, in diesem Falle nicht, da sich die Typen "dynamisch", je nach Wert des Attributes in einem Tag, darauf folgend ändern. Ansonsten kann man Typen ja eben schon prüfen.
Ich würde im Gegenteil eher "entryInt", "entryString", usw. für schlechtes Design halten, denn das ist weder flexibel, noch einfach zu verarbeiten, und zudem aufgeblasen.
Die Namen sind vielleicht schlecht gewählt gewesen und aufgeblasen mag es auch sein, aber damit wäre das Validieren eben möglich. Natürlich muss man Prioritäten setzen, was einem da lieber / wichtiger ist. Will ich alles bis ins kleineste Detail überprüfen, wird das Dokument zwangsläufig komplexer, zudem wenn man dazu noch universell bleiben will. WSDL, SOAP und Co. fallen mir da spontan ein.

Ich habe das Dokument mal entsprechend angepasst und eine Schemadatei angelegt, sowie das Validieren gezeigt.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
Jerry
User
Beiträge: 13
Registriert: Freitag 29. Oktober 2010, 15:00

Hyperion hat geschrieben:Aber bevor ich lange philosophiere, vielleicht ist das ja auch vorgegeben und Du musst jetzt damit klarkommen :-D
Yep, so siehts aus :D Großartig ändern kann ich da jetzt nix...
BlackJack hat geschrieben:@Jerry: Ich weiss nicht ob ich den letzten Satz vor dem "Frowney" richtig interpretiere, aber Du weisst, dass die API von `lxml.etree` eine etwas erweiterte `ElementTree`-API ist!?
Ja, weiss ich. Aber die beiden ähneln sich doch sehr, und beide sind mir viel lieber als der ganze Rest. Allein um Attribute auszulesen muss ich mit den Qt Klassen sowas schreiben

Code: Alles auswählen

self._reader.attributes().value('name').toString()
, was mich nebenbei auch zwingt QRegExp zu benutzen, ich muss auch auf QString Methoden wir trimmed(), oder toLower() anstatt strip() und lower() zurückgreifen, oder ich caste mich doof und dämlich. Ganz davon abgesehen, dass das alles obsolet wird, sobald nach python3 portiert wird...
Nur weil ich paranoid bin, heisst das noch lange nicht, dass ich nicht verfolgt werde!
Antworten