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
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.