xml einlesen

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

Hallo,

Na ich frag dann noch mal glatt hier obwohl ich kein Javafreund bin. Aber es gibt nichts was man nicht mit Java machen kann:)
Und zwar habe ich für nen paar sequentielle Dateien eine XML angefertigt welche die Struktur der sequentiellen Dateien
beschreibt. Mit einem importtool soll dann zuerst die xml eingelsen werden welche dan die Struktur der Tabelle
festlegt. Anschließend soll die sequentielle Datei reingeladen werden, welche ja die Tabelle füllt.
Die XML und sequentielle Datei hab ich. Ist Python dazu geeignet um schnell so nen kleines importskript
zu basteln? Hat jemad ein par Ansatzpunkte für mich?

So sieht die XML aus:

Code: Alles auswählen

<Media>
<Name>CD Nummer 1</Name>
<Table>
<URL>Test.ASC</URL>
<Name>...</Name>
<Description>...</Description>


<!-- Spezifiziert den Dezimaltrenner -->
<DecimalSymbol>,</DecimalSymbol>
<SkipNumBytes>97</SkipNumBytes>
<FixedLength>
<FixedColumn>
<Name>NUMMER</Name>
<Numeric/> 
<FixedRange>
<From>97</From>
<Length>4</Length>
</FixedRange>
</FixedColumn>
<FixedColumn>
<Name>Name</Name>
<AlphaNumeric/> 
<FixedRange>
<From>101</From>
<Length>12</Length>
</FixedRange>
</FixedColumn>
Praktisch ist nur das Name, From und Lenght Tag wichtig würd ich sagen zur Auswertung.
Ich hoffe jemand hat wertvolle Tipps für mich:)

MFG

Lara

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

Anonymous hat geschrieben:Na ich frag dann noch mal glatt hier obwohl ich kein Javafreund bin.
Kein Problem, wir sind es auch nicht :D

Hmm, vermutlich bin ich heute ganz besonders doof, aber ich verstehe das Problem nicht so ganz.

Also: du hast die vorliegende XML Datei, die wenn ich sie mir ansehe gar keine wohlgeformte XML Datei ist. Von welcher Tabelle sprichst du?

Am besten wäre es, du postest mal ein Stück deiner Eingangsdaten und schreibst was du rausbekommen willst.

Python kann gut mit XML umgehen, es gibt dazu sogar das Buch Python & XML.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Anonymous hat geschrieben:Na ich frag dann noch mal glatt hier obwohl ich kein Javafreund bin. Aber es gibt nichts was man nicht mit Java machen kann:)
Hä??? Hier ist kein Javaforum sondern ein Python Forum! Im übrigen kann man ín Python IMHO auch alles machen ;)

Such mal im Forum mal nach "XML"!

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Gast

Hi,


konzentrier dich nur auf diesen Teil.
Praktisch soll jetzt Zeile für Zeil geparst werden bis auf ein Name Tag gestossen wird. Der Name im Tag muss er sich merken und dazu auch noch den Typ und die länge des Feldes. Dann gehts er weiter bis zum nächsten Namen Tag.

Code: Alles auswählen

<FixedColumn> 
<Name>NUMMER</Name> 
<Numeric/> 
<FixedRange> 
<From>97</From> 
<Length>4</Length> 
</FixedRange> 
</FixedColumn> 
<FixedColumn> 
<Name>Name</Name> 
<AlphaNumeric/> 
<FixedRange> 
<From>101</From> 
<Length>12</Length> 
</FixedRange> 
</FixedColumn> 
Wegen der Tabelle meine ich das so: Es soll eine neue Tabelle in meiner mysql datenbank angelgt werden.
paraktisch CREATE TABLE Daten
(
Nummer INTEGER(4),
Name VARCHAR(12),
);

Wobei er die Daten zur Erstellung aus der XML Datei holt.
Ich hoff du konntest mir folgen:)

MFG

Lara

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

Diesmal konnte ich dir wirklich problemlos folgen. Ich schreib dir gleich mal eine recht simple Lösung, moment.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
ProgChild
User
Beiträge: 210
Registriert: Samstag 9. April 2005, 10:58
Kontaktdaten:

jens hat geschrieben:
Anonymous hat geschrieben:Na ich frag dann noch mal glatt hier obwohl ich kein Javafreund bin. Aber es gibt nichts was man nicht mit Java machen kann:)
Hä??? Hier ist kein Javaforum sondern ein Python Forum! Im übrigen kann man ín Python IMHO auch alles machen ;)
Hey ihr beiden! Habt ihr beide schon mal versucht nen Bootloader in Java oder Python zu schreiben? :roll:
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

ProgChild hat geschrieben:Hey ihr beiden! Habt ihr beide schon mal versucht nen Bootloader in Java oder Python zu schreiben? :roll:
Nein, aber den ganzen Rest drumrum ;)

@Lara:
Wie wäre es denn mit so einer Lösung, sie ist nicht besonders schön, jedoch kommt sie auch problemlos mit defekten XML-Dateien aus. Bei Fragen kannst du dich gerne melden, ich habe irgendwie keine Lust gehabt Kommentare in den Code zu schreiben 8)

Code: Alles auswählen

#!/usr/bin/env python
# -*- encoding: latin-1 -*-

import re

def parsedata(f):
    name_rex = re.compile(r'(?<=\<Name>).*(?=</Name>)')
    len_rex = re.compile(r'(?<=\<Length>).*(?=</Length>)')
    
    currentname = ''
    values = {}

    for line in f:
        name = name_rex.findall(line)
        if name != []:
            currentname = name[0]
            values[currentname] = {}
    
        length = len_rex.findall(line)
        if length != []:
            values[currentname]['length'] = length[0]
        
        if '<Numeric/>' in line:
            values[currentname]['type'] = 'INTEGER'
        elif '<AlphaNumeric/>' in line:
            values[currentname]['type'] = 'VARCHAR'
    
    return values

def create_sql(values):
    sql = 'CREATE TABLE Daten\n(\n'
    for key, item in values.items():
        sql += '%(name)s %(type)s(%(length)s)\n' % {'name' : key, 'type' : item['type'], 'length' : item['length'] }
    sql += ');'
    return sql

f = file('pseudo.xml', 'r')
values = parsedata(f)
f.close()

print create_sql(values)
Edit: Regex angepasst.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
ProgChild
User
Beiträge: 210
Registriert: Samstag 9. April 2005, 10:58
Kontaktdaten:

Leonidas hat geschrieben:@Lara:
Wie wäre es denn mit so einer Lösung, sie ist nicht besonders schön, jedoch kommt sie auch problemlos mit defekten XML-Dateien aus.
Aber da oben steht doch valiedes XML, außer dass <Media>, <Table> und <FixedLength> nicht geschlossen werden. Ich denke, dass das aber einfach nur weggelassen wurde. Warum also nicht minidom oder ähnliches benutzen?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

ProgChild hat geschrieben:Aber da oben steht doch valiedes XML, außer dass <Media>, <Table> und <FixedLength> nicht geschlossen werden. Ich denke, dass das aber einfach nur weggelassen wurde. Warum also nicht minidom oder ähnliches benutzen?
Davon abgesehen fehlt ein root-Element. Gut möglich, dass es weggelassen wurde.

Okay, ProgChild gib uns ein Beispiel mit minidom, ich kann es jetzt noch nicht. Allerdings hatte ich sowieso vor eine Version mit XML-Parser so zur Übung zu schreiben, jedoch kann das noch etwas dauern, da ich mich erstmal reinlesen muss.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
ProgChild
User
Beiträge: 210
Registriert: Samstag 9. April 2005, 10:58
Kontaktdaten:

Leonidas hat geschrieben:Davon abgesehen fehlt ein root-Element. Gut möglich, dass es weggelassen wurde.
Ich hab <Media> dafür gehalten...
Leonidas hat geschrieben:Okay, ProgChild gib uns ein Beispiel mit minidom, ich kann es jetzt noch nicht. Allerdings hatte ich sowieso vor eine Version mit XML-Parser so zur Übung zu schreiben, jedoch kann das noch etwas dauern, da ich mich erstmal reinlesen muss.
Ich halte hier Expat für angebrachter, weil wir nur lesen und nicht unbedingt die Ganze Tabelle in den RAM laden müssen. Darum hier ein Beispiel mit Expat.

Unter test.xml gespeichert:

Code: Alles auswählen

<?xml version="1.0"?>
<Media>
<Name>CD Nummer 1</Name>
<Table>
<URL>Test.ASC</URL>
<Name>daten</Name>
<Description>...</Description>

<!-- Spezifiziert den Dezimaltrenner -->
<DecimalSymbol>,</DecimalSymbol>
<SkipNumBytes>97</SkipNumBytes>
<FixedLength>
<FixedColumn>
<Name>NUMMER</Name>
<Numeric/>
<FixedRange>
<From>97</From>
<Length>4</Length>
</FixedRange>
</FixedColumn>
<FixedColumn>
<Name>Name</Name>
<AlphaNumeric/>
<FixedRange>
<From>101</From>
<Length>12</Length>
</FixedRange>
</FixedColumn>

</FixedLength>

</Table>
</Media>
Und der script:

Code: Alles auswählen

import xml.parsers.expat

class Reader:

	def read( self, filename ):
		self.query = 'CREATE TABLE '
		self.path = []

		p = xml.parsers.expat.ParserCreate()

		p.StartElementHandler = self.start_element
		p.EndElementHandler = self.end_element
		p.CharacterDataHandler = self.char_data

		f = open( filename, 'r' )
		p.ParseFile( f )
		f.close()

	def start_element( self, name, attrs):
		path = "/" . join( self.path )
		if path == 'Media/Table/FixedLength/FixedColumn':
			if name == 'Numeric':
				self.query += "INTEGER("
			if name == 'AlphaNumeric':
				self.query += "VARCHAR("
			
		self.path.append( name )
		self.cur_data = ''
	
	def end_element( self, name):
		path = "/" . join( self.path )
		if path == 'Media/Table/Name':
			self.query += self.cur_data + "\n(\n"
		
		if path == 'Media/Table/FixedLength/FixedColumn/Name':
			self.query += self.cur_data + " "

		if path == 'Media/Table/FixedLength/FixedColumn' + \
			'/FixedRange/Length':
			self.query += self.cur_data

		if path == 'Media/Table/FixedLength/FixedColumn':
			self.query += "),\n"

		if path == 'Media/Table':
			self.query += ");\n"


		del self.path[-1]
	
	def char_data( self, data):
		self.cur_data += data

	def get_query( self ):
		return self.query


r = Reader()
r.read( 'test.xml' )
print r.get_query()
Leonidas, ich wollte weder dein Script noch dich nicht kritisieren. Du verbringst hier sehr viel Zeit, was ich sehr gut finde. Normalerweise ist es ja nicht Sinn des Forums, die Aufgaben der anderen Leute hier zu lösen, sondern sie dabei zu unterstüzen, aber ich hab das mal als herausforderung genommen. Expat hab ich noch nie vorher benutzt, minidom zwar schon, das ist hier aber nicht so geeignet.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

ProgChild hat geschrieben:Leonidas, ich wollte weder dein Script noch dich nicht kritisieren.
Nein, habe ich auch nicht als Kritik aufgefasst sondern als alternativen Lösungsvorschlag.
ProgChild hat geschrieben:Normalerweise ist es ja nicht Sinn des Forums, die Aufgaben der anderen Leute hier zu lösen, sondern sie dabei zu unterstüzen, aber ich hab das mal als herausforderung genommen.
Ich auch, deswegen habe ich ja auch das Script fertiggeschrieben.
ProgChild hat geschrieben:Expat hab ich noch nie vorher benutzt, minidom zwar schon, das ist hier aber nicht so geeignet.
Und ich habe mich die letzten Jahre erfolgrecuh um das Thema XML gedrückt und vorher nur mit SAX beschäftigt. Werd ich wohl nachholen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
TripleH
User
Beiträge: 29
Registriert: Donnerstag 11. Dezember 2003, 12:58

Hi,

Ich hab mir das Programm mal angeschaut. Beim ausfürhren des Skriptes kommt ein Fehler an
dieser Stelle:

if path == 'Media/Table/FixedLength/FixedColumn' + \

Und zwar kommt die Fehlermeldung invalid token. Ursache ist wohl der Backslash oder?

Nun ja mir ist dieses Skript nicht 100% klar.

Also verbessert mich wenn ich was falsch interpretiere:

In der Funtion "read" wird der xml Parser initialisiert und auch die einzelnen Funktionen.
Dann wird die xml eingelesen und geparst.
Dann kommt die Funton start_element. Das hat ähnlichkeit mir SAX in Java.
Sie wird aufgerufen sobald der Parser das erste Tag findet.
Die Zeile kann ich nicht ganz deuten. path = "/" . join( self.path )
Dann werden die einzigen 2 Dinge wie numeric und alphanumeric durch die If Abfrage
dekodiert. Bei den 2 Zeilen häng ich leider auch schon wieder:)
self.path.append( name )
self.cur_data = ''

Danach kommt dann die Funtion end_element welche die schleißenden Tags verarbeitet.
Grob gesagt wird mit if Abfragen geschaut an welcher Stelle im xml Code
man sich befindet und dementsprechend wird das jeweilige zeichen dem query zugefügt oder?
Was machen diese 2 Funktionen?

def char_data( self, data):
self.cur_data += data

def get_query( self ):
return self.query

Die erste behandelt die Inhalte der Tags und die 2 liefert den komplette query zurück?

Ich hoffe jemand kann zu meinem Verstandnis nocht etwas beitragen:)

Wenn man dieses Skript mal richtig testen möchte:

1. müßte man noch den connect zu ner Datenbank machen. Kann man Python mit Mysql
verbinden. Wo gibs infos zwecks Treiber?

2. um das Skript laufen zu lassen müßte man da die ganze Klaee noch in eine Funtion packen?

Beste Grüße

Basti
ProgChild
User
Beiträge: 210
Registriert: Samstag 9. April 2005, 10:58
Kontaktdaten:

TripleH hat geschrieben:Beim ausfürhren des Skriptes kommt ein Fehler an
dieser Stelle:

if path == 'Media/Table/FixedLength/FixedColumn' + \

Und zwar kommt die Fehlermeldung invalid token. Ursache ist wohl der Backslash oder?
Du hast hinter dem Backslash ein Leerzeichen eingefügt. Das ist an dieser Stelle verboten.

Du kannst alternativ auch folgendes schreiben.

Code: Alles auswählen

if path == 'Media/Table/FixedLength/FixedColumn/FixedRange/Length': 
TripleH hat geschrieben: Die Zeile kann ich nicht ganz deuten. path = "/" . join( self.path )
Diese Zeile fügt alle Einträge der Liste self.path zu einem String mit dem Slash als Trennzeichen zusammen.
TripleH hat geschrieben:Bei den 2 Zeilen häng ich leider auch schon wieder:)
self.path.append( name )
self.cur_data = ''
Der Liste self.path wird ein String mit dem Namen des gerade geöffneten XML Tags hinzugefügt. self.cur_data wird ein Leerer string zugewiesen.
TripleH hat geschrieben:Wenn man dieses Skript mal richtig testen möchte:

1. müßte man noch den connect zu ner Datenbank machen. Kann man Python mit Mysql
verbinden. Wo gibs infos zwecks Treiber?
Schau mal im Wiki, da ist ein Link zum MySQL Modul.
TripleH hat geschrieben:2. um das Skript laufen zu lassen müßte man da die ganze Klaee noch in eine Funtion packen?
Nein. Einfach so als Python Datei abspeichern. Als Textausgabe solltest du das SQL Query bekommen.
Gast

Hallo Leonidas,

ich versuche gerade, SAX zu verwenden, leider gibt es ein Problem:
im Buch gibt es ein Beispiel, wie man make_parser zu verwenden kann. Aber für meinen Fall ist parseString etwas sinnvoller (aus Python-dokument). Mit make_parser wird als Default ExpatParser verwendet, der keine parseString vorhanden ist.

Meine Frage, wie kann man ein String (aus XML-tags) parsen?

Danke für einen Hinweis oder Tipps!

MfG
TripleH
User
Beiträge: 29
Registriert: Donnerstag 11. Dezember 2003, 12:58

Hi,

Dank dir. Progchild. Denk habs verstanden. Ich hab mal nen bicßehn rumgespielt und die mit der Create Anweisung die Tabelle in der Datenbank erstellt.

Jetzt hab ich nur mal ne Frage. Die xml Struktur in eine Datenbank zu schreiben ist nicht so schwer. Nur ich hab ma oben bei Lara gelesen. Ziel einer jeden Tabelle in einer Datenbank ist es ja sie zu füllen. Ich hab jetzt mal zu der Test.xml mal eine sequentielle Datei erstellt.

ganz einfach. sind ja nur 2 Felder
Nummer und Name.

das würde dann wohl so aussehen.

ersten 97 zeichen überlesen 1234siegfreidfre
ersten 97 zeichen überlesen 3456herrmanfre

so könnte ja die test.txt aussehen die durch die test.xml beschrieben wurde. Nur mir ist eine schon theoretisch bei der Umsetztung etwas nicht klar. Ich hoffe jemande kann mir helfen:
Und zwar muss ich mir den ersten Feldblock in der xml suchen und dort finde ich ja die Position wo er in der test.txt anfängt und wie lang er ist.
Nun muss ich mit dieser info in der txt an die Stelle springen und den Feldinhalt wieder speichern für das insert query.
Irgendie hab ich ne Blockade im Kopf wegen den 2 Dateien die jetzt gleichzeitig zu handeln sind.

Kann mir jemand nen Denkanstoss geben?

MFG

Basti
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Code: Alles auswählen

for line in open("Datendatei").readlines():
    line = line[SKIPBYTES:]
    feld1 = line[:4]
    feld2 = line[4:]
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Anonymous hat geschrieben:ich versuche gerade, SAX zu verwenden, leider gibt es ein Problem:
im Buch gibt es ein Beispiel, wie man make_parser zu verwenden kann. Aber für meinen Fall ist parseString etwas sinnvoller (aus Python-dokument). Mit make_parser wird als Default ExpatParser verwendet, der keine parseString vorhanden ist.

Meine Frage, wie kann man ein String (aus XML-tags) parsen?
Bin zwar kein Experte, was SAX angeht, aber parseString findest du folgendermaßen:

Code: Alles auswählen

>>> import xml.sax
>>> xml.sax.parseString
<function parseString at 0x502d99f0>
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
TripleH
User
Beiträge: 29
Registriert: Donnerstag 11. Dezember 2003, 12:58

Hi,


zum Beitrag von Joghurt.
ja soweit war auch meine Idee.
So kann man Zeileninhalt speichern. Den Syntax SKIPBYTES klappt nicht. Brauchman ja auch letztendlich nicht,
Wenn die einzelnen Felder durch Positionsangaben Abgrenzen kann. wie z.B.
feld1 = line[104:108]
feld2 = line[108:112]

So meine Frage ist jetzt ob es nicht einen Syntax gibt der auf dem zuvorigenFeld aufbaut.
Also Praktisch so:

line = line[Skipbytes:104] //erste 100 zeichen werden übersprungen
feld1 = line[lenth:4]
feld2 = line[lenth:4]

Praktisch das anhand der Längenangabe automatisch weitergegangen wird in der Zeile oder zur Not

feld1 = line[104:length=4]
feld2 = line[108:lenth =4]

Diesen Syntax gibs so nicht sonst würd ich nicht so fragen.Aber ich hoff ihr wisst was ich meine.
Ich will den Syntax umgehen das, dass die letzte Postionsabgabe des ersten Feldes die erste
des 2. Feldes ist.

Ich hoffe jemand kann mir helfen.

MFG

Bast
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ich glaube ein ähnliches Problem hatte ich auch mal, siehe http://www.python-forum.de/viewtopic.php?t=3011

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Zum ursprünglichen Problem einen Parser zu schreiben, der die XML Datei zu SQL verarbeitet: ich habe nun meinen ersten Parser soweit verbessert, dass er sowohl Reguläre Ausdrücke als auch SAX2 verwenden kann. DOM kommt in späteren Versionen dazu.

Ich bin von der folgenden XML-Datei ausgegangen, die der von ProgChild in großen Teilen ähnlich ist.

Code: Alles auswählen

<?xml version="1.0"?>

<Media>
    <Name>CD Nummer 1</Name>
    <Table>
        <URL>Test.ASC</URL>
        <Name>daten</Name>
        <Description>...</Description>

        <FixedColumn>
            <Name>NUMMER</Name>
            <Numeric/>
    
            <FixedRange>
                <From>97</From>
                <Length>4</Length>
            </FixedRange>
        
        </FixedColumn>
    
        <FixedColumn>
            <Name>Name</Name>
            <AlphaNumeric/>
        
            <FixedRange>
                <From>101</From>
                <Length>12</Length>
            </FixedRange>
        
        </FixedColumn>
    </Table>
</Media>
Das Programm, das diese Datei parsen kann, sieht so aus:

Code: Alles auswählen

#!/usr/bin/env python
# -*- encoding: latin-1 -*-

import re
import xml.sax, xml.sax.handler

def parsedata_re(filename):
    """Parses the XML-file using regular expressions"""
    f = file(filename, 'r')
    
    # regex for matching needed tags: Name and Length
    name_rex = re.compile(r'(?<=\<Name>).*(?=</Name>)')
    len_rex = re.compile(r'(?<=\<Length>).*(?=</Length>)')
    
    currentname = ''
    values = {}
    parse_enabled = False

    for line in f:
        if '<FixedColumn>' in line:
            # only parse inside FixedColumn
            parse_enabled = True
        elif '</FixedColumn>' in line:
            parse_enabled = False
        
        if parse_enabled:
            name = name_rex.findall(line)
            if name != []:
                currentname = name[0]
                values[currentname] = {}
    
            length = len_rex.findall(line)
            if length != []:
                values[currentname]['length'] = length[0]
        
            if '<Numeric/>' in line:
                values[currentname]['type'] = 'INTEGER'
            elif '<AlphaNumeric/>' in line:
                values[currentname]['type'] = 'VARCHAR'
    
    f.close()
    return values

def create_sql(values):
    """Creates a SQL statement"""
    sql = 'CREATE TABLE Daten\n(\n'
    for key, item in values.items():
        sql += '%(name)s %(type)s(%(length)s)\n' % {'name' : key, 'type' : item['type'], 'length' : item['length'] }
    sql += ');'
    return sql

class TablHandler(xml.sax.handler.ContentHandler):
    def __init__(self):
        self.in_name = False
        self.in_fc = False
        self.in_len = False
        
        self.values = {}
        self.currentname = ''
        
    def startElement(self, name, attrs):
        
        # check what tag was opened
        if name == 'FixedColumn':
            # we're in FixedColumn, so we are permitted to parse Name-tags
            self.in_fc = True
        elif name == 'Name' and self.in_fc:
            # only permit parsing if we are in FixedColumn
            self.in_name = True
        elif name == 'Length':
            # we're in Length tag
            self.in_len = True
        elif name == 'Numeric':
            # the empty tag Numeric occured
            self.values[self.currentname]['type'] = 'INTEGER'
        elif name == 'AlphaNumeric':
            self.values[self.currentname]['type'] = 'VARCHAR'
    
    def characters(self, data):
        if self.in_name:
            self.currentname = data
            self.values[self.currentname] = {}
            
        elif self.in_len:
            self.values[self.currentname]['length'] = data
    
    def endElement(self, name):
        if name == 'FixedColumn':
            self.in_fc = False
        elif name == 'Name':
            self.in_name = False
        elif name == 'Length':
            self.in_len = False
        

def parsedata_sax(filename):
    parser = xml.sax.make_parser()
    handler = TablHandler()
    parser.setContentHandler(handler)
    parser.parse(filename)
    return handler.values

def main():
    name = 'tabl.xml'
    #values = parsedata_re(name)
    values = parsedata_sax(name)

    print create_sql(values)

if __name__ == '__main__':
    main()
Ich mag SAX irgendwie trotzdem nicht, gar nicht auszudenken, wie so ein Programm in Java aussehen würde.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten