etree Kommentare entfernen

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
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Folgendes Problem, ich parse mit etree ein paar xml Dateien, ermittle die root und
iteriere über die restliche Strucktur.
Nun habe ich aber das Problem das bei jeder iteration auch die Kommentar-tags
mit auftauchen, die ich dort aber logischerweise nicht gebrauchen kann.

Ich könnte jetzt bei jeder Schleife so eine abfrage machen "isinstance(subelem.tag, type(etree.Comment))", ist aber im Grunde ziemlich unschön.

Also meine Frage, gibt es eine Möglichkeit mit etree durchweg Kommentare zu ignorieren ?

Ein minimal Beispiel könnte so aussehen:
a.xml

Code: Alles auswählen

<root>
    <!-- elem 0 -->
    <elem>
        <id>0</id>
    </elem>
    <elem>
        <!--ID 1 -->
        <id>1</id>
    </elem>
</root>
anything.py

Code: Alles auswählen

from lxml import etree

root = etree.parse("a.xml").getroot()
for elem in root:
    for subelem in elem:
         print(subelem.tag, subelem.text)
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
BlackJack

@Xynon1: Interessant zu wissen -- da verhält sich das `ElementTree` aus der Standardbibliothek anders.

Mit `xpath()` geht es anscheinend recht einfach:

Code: Alles auswählen

In [121]: etree.dump(r)
<root>
    <!-- elem 0 -->
    <elem>
        <id>0</id>
    </elem>
    <elem>
        <!--ID 1 -->
        <id>1</id>
    </elem>
</root>
In [122]: r.xpath('*')
Out[122]: [<Element elem at a281b6c>, <Element elem at a281b44>]
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Danke, hat mich auch verwundert warum das nicht gleich ist.
scheinst ja deiner Nummerierung entsprechend auch ein wenig gebraucht zu haben.

Problem an der Sache ist nur noch das ich das auch überall aufrufen muss, da ich noch bis zu einer ebene tiefer haben kann und das xpath das auch nur für eine Ebene entfernt.
Aber es ist auf jedenfall schonmal kürzer :D
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
BlackJack

@Xynon1: Das IPython läuft schon etwas länger. ;-) Du wirst hier im Forum auch sicher Snippets von mir finden, wo der Zähler bei >300 ist. Server und ``screen`` oder "suspend to disk" machen's möglich. :-)

Ich habe den Einwand nicht so recht verstanden!? Geht's einfach nur darum, dass Du für die innere Schleife noch einmal `xpath()` aufrufen müsstest? Zumindest bei diesem künstlichen Beispiel kann man sich die innere Schleife sparen:

Code: Alles auswählen

In [123]: r.xpath('*/*')
Out[123]: [<Element id at a3b9cac>, <Element id at a3b9be4>]

In [124]: r.xpath('elem/id')
Out[124]: [<Element id at a3b9cac>, <Element id at a3b9be4>]
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Ok, wie fütterst du dann "r" ?
Bei mir kommt nämlich nicht das gleiche heraus, ich habe bei xpath("*/*") gar keine Rückgabe mehr.

BlackJack hat geschrieben:@Xynon1: Das IPython läuft schon etwas länger. ;-) Du wirst hier im Forum auch sicher Snippets von mir finden, wo der Zähler bei >300 ist. Server und ``screen`` oder "suspend to disk" machen's möglich. :-)
War auch nur ein Scherz :D,
aber ich glaube das @Xynon1 kannst du dir sparen, da momentan nur wir beide hier schreiben, also kann ich dann schon vermuten wer gemeint ist. :mrgreen:
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
BlackJack

@Xynon1: Das @...: mache ich grundsätzlich. Habe in der Vergangenheit schon öfter erlebt das jemand "dazwischen gepostet" hat, und es dann nicht mehr klar war, auf wen sich meine Antwort bezog. Mittlerweile warnt die Forumssoftware ja davor, aber ich habe mich nun mal daran gewöhnt. Und in anderen Foren gibt's keine Warnung.

Code: Alles auswählen

In [142]: r = etree.fromstring(source)
Wobei `source` an eine Zeichenkette mit dem XML-Quelltext gebunden ist.
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

:idea: - habe meinen Fehler.

Bin einmal zu oft drüber gelaufen, xpath teilt mir die root ja schon. :oops:
Mit anderen Worten ich habe am ende über die Id-SubElement iteriert und diese besitzen ja keine Chields mehr, also bekam ich eine leere Rückgabe.


Hier noch wieder eine Frage, kann man getrost die "parse"-Methode nutzen oder ist es besser with open und dann mit der "fromstring"-Methode ?
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
BlackJack

@Xynon1: Wenn die Daten in einer Datei vorliegen, dann würde ich `parse()` verwenden. Ich wollte für das Beispiel hier nur keine extra Datei anlegen und hab's per kopieren und einfügen in die IPython-Sitzung kopiert.
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Ok, danke nochmals.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Antworten