String aus XML-Tag auslesen (xml.dom.minidom)

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
Floqqi

Hallo Community,

ich möchte wissen, wie ich einen String zwischen einem Tag auslesen kann.
Also quasi: <name>Egon</name>, wie bekomm ich da "Egon" raus?

Mit einem Attribut geht das ja ganz einfach mit node.getAttribute("name"). Allerdings gibt es keine deratige Methode wie z. B. node.getValue(). Mit node.data bekomme ich nur einen leeren String zurück.

XML:

Code: Alles auswählen

<?xml version="1.0" encoding="UTF-8"?>
<table name="logfile">
	<row>
		<idlogfile>
			1
		</idlogfile>
		<ip>
			172.18.222.2
		</ip>
		<user>
			hans
		</user>
		<time>
			2009-01-20 23:53:53
		</time>
		<method>
			GET
		</method>
		<uri>
			/VirtualHostBase/http//bla.de/VirtualHostRoot/
		</uri>
		<protocol>
			HTTP/1.1
		</protocol>
		<status>
			200
		</status>
		<size>
			39738
		</size>
	</row>
</table>
Python:

Code: Alles auswählen

from xml.dom import minidom as dom
from xml.dom import Node

table = dom.parse("logfiles.xml").getElementsByTagName("table")
if len(table) > 0:
    table = table[0]
        
for row in table.childNodes:
    if row.nodeName[0] != "#":
        for content in row.childNodes:
            if content.nodeType == Node.TEXT_NODE:
                print content.data
                # Funktioniert nicht, gibt nur leeren String zurück..
Ich möchte jetzt alle Werte der Kindknoten von "row" herausparsen.

Mit freundlichen Grüßen
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Muss es denn `mindom` sein? Wie wäre es mit `ElementTree`?:

Code: Alles auswählen

In [208]: from xml.etree import ElementTree as etree

In [209]: root = etree.fromstring(u"""<?xml version="1.0" encoding="UTF-8"?>
<table name="logfile">
   <row>
   usw ...
""")

In [242]: root.find(u"row/user").text
Out[242]: '\n         hans\n      '
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
lunar

@Floqqi: Vergiss minidom:

Code: Alles auswählen

from xml.etree import ElementTree as etree

table = etree.parse('logfiles.xml').getroot()
for row in table.findall('row'):
    for cell in row:
        print(cell.text.strip())
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Wenn es minidom sein muss: Ein "roher" DOM behandelt Text als eigenen Knoten-Typ, daher:

Code: Alles auswählen

document = dom.parseString("<a><b>Hallo</b></a>")
for b in document.getElementsByTagName("b"):
    print b.firstChild.nodeValue
Man bedenke, dass auch Leerzeichen zwischen Elementen als Text-Knoten repräsentiert werden.

Stefan
problembär

Mein Vorschlag wäre gewesen:

Code: Alles auswählen

from xml.dom import minidom
from xml.dom import Node

def walkNode(parent):
    for node in parent.childNodes:
        if node.nodeType == Node.TEXT_NODE:
            content = node.nodeValue.strip()
            if content:
                print content
        walkNode(node)

document = minidom.parse("logfiles.xml")
table = document.getElementsByTagName("table")
if len(table) > 0:
    table = table[0]

for row in table.childNodes:
    if not row.nodeName.startswith("#"):
        walkNode(row)
Aber sma's Hinweis klingt recht gut.
Floqqi

Vielen Dank an alle - vor allem mit dem Tipp `ElementTree`.
Mit ElementTree funktioniert das alles viel komfortabler und einfacher. Danke an lunar, dein Script hat super funktioniert.

Problem gelöst :)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Floqqi hat geschrieben:Vielen Dank an alle - vor allem mit dem Tipp `ElementTree`.
Mit ElementTree funktioniert das alles viel komfortabler und einfacher. Danke an lunar, dein Script hat super funktioniert.

Problem gelöst :)
Vielleicht mal als Hinweis für die Zukunft: `lxml` ist ein sehr gutes Paket in Sachen xml, ich wage mal zu behaupten das beste im Python-Umfeld. Das implementiert die ElementTree-API, kann darüber hinaus aber noch weit mehr, u.a. XPath-Queries auf Knoten / Dokument-Objekten.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Floqqi

Hyperion hat geschrieben:
Floqqi hat geschrieben:Vielen Dank an alle - vor allem mit dem Tipp `ElementTree`.
Mit ElementTree funktioniert das alles viel komfortabler und einfacher. Danke an lunar, dein Script hat super funktioniert.

Problem gelöst :)
Vielleicht mal als Hinweis für die Zukunft: `lxml` ist ein sehr gutes Paket in Sachen xml, ich wage mal zu behaupten das beste im Python-Umfeld. Das implementiert die ElementTree-API, kann darüber hinaus aber noch weit mehr, u.a. XPath-Queries auf Knoten / Dokument-Objekten.
Sieht interessant aus - werde ich mir mal beim nächsten Gebrauch genauer anschauen. Danke :)
Antworten