Mit SAX könnte man das so machen:
Code: Alles auswählen
from xml.sax import ContentHandler, parseString
source = """\
<Koordinaten>
<Punkt1>
<X>10</X>
<Y>30</Y>
</Punkt1>
<Punkt2>
<X>40</X>
<Y>80</Y>
</Punkt2>
<Punkt3>
<X>90</X>
<Y>100</Y>
</Punkt3>
<Punkt4>
<X>172</X>
<Y>123</Y>
</Punkt4>
<Punkt5>
<X>122</X>
<Y>220</Y>
</Punkt5>
</Koordinaten>
"""
class CoordinateHandler(ContentHandler):
def __init__(self):
ContentHandler.__init__(self)
self.last_x = None
self.text = ''
self.coordinates = list()
def startElement(self, name, attrs):
self.text = ''
def endElement(self, name):
if name == 'X':
self.last_x = int(self.text)
elif name == 'Y':
self.coordinates.append((self.last_x, int(self.text)))
self.last_x = None
def characters(self, content):
self.text += content
def parse_coordinates(source):
handler = CoordinateHandler()
parseString(source, handler)
return handler.coordinates
if __name__ == '__main__':
print parse_coordinates(source)
Wenn es auch eine externe Bibliothek sein darf, dann ist ElementTree für XML ganz nett:
Code: Alles auswählen
from StringIO import StringIO
from elementtree.ElementTree import iterparse
source = ...
def parse_coordinates2(source):
result = list()
last_x = None
last_y = None
for event, node in iterparse(source):
if node.tag == 'X':
last_x = int(node.text)
elif node.tag == 'Y':
last_y = int(node.text)
elif node.tag.startswith('Punkt'):
result.append((last_x, last_y))
last_x = None
last_y = None
return result
if __name__ == '__main__':
source_file = StringIO(source)
print parse_coordinates2(source_file)
In beiden Fällen wird das XML wahrscheinlich in einer Datei stehen, dann brauchst Du es nicht in ein `StringIO` Objekt verpacken und kannst bei der SAX Lösung die `parse()` Funktion anstelle der `parseString()` Funktion benutzen.