Fragen zum XML auslesen per Modul

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
Xenon-777
User
Beiträge: 2
Registriert: Freitag 9. Februar 2007, 12:04

also ... ich hab mich mal 3-4 Tage durchs Netz gekämpft um mal so was ähnliches wie ein XML zu Dict Modul zu bauen. Etwas ähnliches hatte ich sogar schon gefunden nur leider sehr fehleranfällig und ohne das Attribute unterstützt werden. So ... hier mal das Modul:

Code: Alles auswählen

from xml.dom.minidom import parse,parseString
from urllib2         import urlopen
from os              import open

def xmlopen(url,enc=None):

	if url[:7].lower() == "http://":
		xmlfd = urlopen(url)
	else:
		xmlfd = open(url,"r")
	if enc == None:
		xmlhl = xmlhead(xmlfd)
		enc = xmlhl['encoding']
		# leider laest sich das bearbeitete xml danach nicht mehr parsen weswegen es neu goeffnet werden muss 
		xmlfd.close()
		xmlfd = urlopen(url)
	xmldoc = parse(xmlfd)
	xmlfd.close()

	return bibxml(xmldoc,enc)

def xmlhead(xmlfd): # Auswerten der Header-Variablen

	xmlc = ""
	xmlhead = ""
	while xmlc != ">":
		xmlhead = xmlhead + xmlc
		xmlc = xmlfd.read(1)
	xmlhead = xmlhead + " />"
	xmlhead = xmlhead.replace("?","")

	attribl = {} 
	head = parseString(xmlhead)
	for attribut in head.childNodes[0].attributes.keys():
		attribl[head.childNodes[0].attributes[attribut].name.encode()] = head.childNodes[0].attributes[attribut].value.encode()
	return attribl

def bibxml(xmldoc,enc):

	name = ""
	bibnodes = {}

	for childnode in xmldoc.childNodes:

		if childnode.nodeType == 1: # Node ist ein Tag
			name = childnode.nodeName.encode(enc)
			# Inhalt
			if childnode.hasChildNodes():
				value = bibxml(childnode,enc)
			elif childnode.nodeValue == None:
				value = childnode.nodeValue
			else:
				value = childnode.nodeValue.encode(enc)

			# Attribute
			if childnode.attributes.keys() != []:
				attribbib = {}
				for attribut in childnode.attributes.keys():
					aname  = childnode.attributes[attribut].name.encode(enc)
					avalue = childnode.attributes[attribut].value.encode(enc)
					attribbib[aname] = avalue
				if value != None:
					value = [{'attribut':attribbib},value]
				else:
					value = {'attribut':attribbib}

			# Eintragen von einen bibliotheks-Eintrag ( zugegeben -> geklaut ;P )
			if value != None:
				if name in bibnodes: 
					if isinstance(bibnodes[name], dict):
						# there is multiple instances of this node - convert to list
						bibnodes[name] = [bibnodes[name]]
					bibnodes[name].append(value)
				else:
					bibnodes[name] = value

		if ((childnode.nodeType == 3) or (childnode.nodeType == 4)): # Node ist ein Text
			if childnode.nodeValue != None:
				value = childnode.nodeValue.encode(enc).replace("\n","")
				value = value.replace("\t","")
				value = value.replace(" ","")
				if value == "":
					continue
			bibnodes = childnode.nodeValue.encode(enc)

	return bibnodes
So ... 2 Probleme hab ich in den code:

1. Wie der aufmerksame Beobachter sehen kann lese ich, falls kein encoding angegeben ist, den ersten Tag aus, lösche die ?, setze ein /> hinten dran und parse das zu einen dict um das encoding, und andere dokumet deklarationen, zu erhalten. Problem bei den ganzen, an gelesenen fd mag der xml.dom parser nicht mehr und .seek() ist bei urlopen nicht möglich. Irgendwelche Ideehen wie man das besser machen kann als die quelle 2 mal zu öffnen? Erstellen einer Datei ist auf einen Unix System zumindest mal heikel und würde ich gerne vermeiden.

2. Es ist ein Fehler in Modul. Das Modul funktioniert soweit, nur bei folgender Konstellation versagt es:

<tag1>
<tag2 attr1="bla" attr2="blub">text1</tag2>
<tag2 attr1="bla" attr2="blub">text2</tag2>
<tag2 attr1="bla" attr2="blub">text3</tag2>
</tag1>

Normalerweise sollte dann in dic es so aussehen das x['tag1']['tag2'] eine liste ist mit 3 Elemente, jedes Elemet wider eine liste mit 2 Elementen wo [0] die Attribute sind und [1] der text. Leider verpackt er das erste auftreten von tag2 falsch so das x['tag1']['tag2'] eine liste aus 4 Elementen ist wo das [0] die Attribute des ersten auftreten von tag2 sind, [1] der text dazu und erst dann die listen für die weiteren tag2 koreckt eingebaut werden. Wo der fehlter liegt hab ich nicht raus gefunden. Vileicht sieht ihn ja einer von euch.

---8<------------

Oha ... ich sehe gerade das es auch mit Dateien so wohl nicht funktionieren würde. das start def werde ich wohl nochmal umschreiben müssen.
Aber trotzdem bin ich für jeden tip dankbar der das Teil optimirt.

Edit (Leonidas): Code-Highlighting eingeschaltet.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Hallo Xenon-777, willkommen im Forum,

Kurze Gegenfrage: Warum nicht einfach ElementTree nehmen? Das unterstützt XML wunderbar, funktioniert schnell und ist bei Python mitgeliefert.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Xenon-777
User
Beiträge: 2
Registriert: Freitag 9. Februar 2007, 12:04

ööööömmmm ... weil es mir bei meiner ganzen Suche in Netz (und meinen tableiste in Firefox ist mitlerweile schon 8-9 Zeilen lang) nie einer empfohlen hat

Eines meiner hauptprobleme mit Python, so sehr ich die sprache auch liebe, ist die documentation. Fraglich ob eine Funktion überhaubt komplet und verständlich sowie mit allen anwendungsmöglichkeiten beschriben wird. Ich hab das xml-dom Wissen das da in Modul steckt locker aus 15-20 verschidenen Qwellen zusammengesucht. Da ist php mit www-php.org richtig gehend vorbildlich.

Aber danke für die Begrüsung, und danke für den tip ... dann mach ich mich mal wider auf die suche :)
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Xenon-777 hat geschrieben:dann mach ich mich mal wider auf die suche :)
Hallo Xenon-777!

Willkommen im Python-Forum!

Jetzt bist du ja im Python-Forum gelandet. Die Forensuche bietet Zugang zu geballtem Python-Wissen. :wink:

Hier ist ein Beispiel zur Verwendung von ElementTree:
http://www.python-forum.de/post-57056.html#57056

Dann habe ich noch zwei Links:
- http://docs.python.org/lib/module-xml.e ... tTree.html
- http://effbot.org/zone/element-index.htm

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Antworten