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.
TripleH
User
Beiträge: 29
Registriert: Donnerstag 11. Dezember 2003, 12:58

Hallo,

achso, muss mans doch nur so machen in dem mans gleich ins dict schreibt.
Gut ich fand diese Struktur:

Code: Alles auswählen

spec = [['NUMMER', {'from': 97, 'length': 4}], 
    ['Name', {'from': 10, 'length': 8}]]
schon zeimlich sinnvoll.

versuch gerade Umzusetzten doch es gibt noch ein kleines Prob:
Der Quelltext ist ja noch immer derselbe ausser das in der Funktion end_element
die werte Ins Dict bzw. Liste eingetragen werden.
Ich habs mir so gedacht:(ich weiß self.query könnte weg)

Code: Alles auswählen

def end_element( self, name): 
        path = "/" . join( self.path ) 
        
        
        if path == 'Media/Table/FixedLength/FixedColumn/Name': 
            self.add_seperator() 
            self.query += "['" + self.cur_data + "'," 
	    list.append([[self.cur_data.encode('latin-1'), {'from': 0, 'length': 0}])
                    
        if path == 'Media/Table/FixedLength/FixedColumn/FixedRange/Length': 
            self.query += "'length': " + self.cur_data + "}]" 

        if path == 'Media/Table/FixedLength/FixedColumn/FixedRange/From': 
            self.query += " {'from': " + self.cur_data + "," 

        if path == 'Media/Table': 
            self.query += "]" 

        del self.path[-1]

so damit würde ich immer diese Grundstruktur der Liste hinzufügen. Das Problem ist das jetzt
der from und lenth wert null sind. Mein plan war es self.cur_data immer auf ner Variablen
zu speichern und dann alles hier:if path == 'Media/Table/FixedLength/FixedColumn/FixedRange/From':
zusammensetzen aber allerdings kommt dann immer die Fehlermeldung:
local variable ''referenced before assgment.
Gut das geht dann schon mal nicht. Allerdings da das Dictionary ein Element der Liste ist fällt es mir schwer
auf den key from zuzugreifen und so den Wert dann in den jeweiligen if Anweisungen zu setzten.
Kann jemand so nett sein und mir noch nen guten Tipp geben?

MFG

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

Hallo,

Ok ich habs jetzt alles in eine Liste bzw. Dict gepackt:

Code: Alles auswählen

def end_element( self, name):
        path = "/" . join( self.path ) 
        
        
        if path == 'Media/Table/FixedLength/FixedColumn/Name': 
            self.add_seperator() 
            self.n = self.cur_data.encode('latin-1')
            
        
           
        if path == 'Media/Table/FixedLength/FixedColumn/FixedRange/From':
            self.f = self.cur_data.encode('latin-1')
          
            

        if path == 'Media/Table/FixedLength/FixedColumn/FixedRange/Length':
            list.append([self.n, {'from': self.f, 'length': self.cur_data.encode('latin-1')}])
        if path == 'Media/Table': 
            self.query += "]" 
            print self.cur_data
        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' ) 
spec = r.get_query().encode('latin-1') 
print spec
print list
     

f = file("C:\\test.txt", 'r') 
for line in f: 
    line = line.splitlines()[0]
    print 'Line: %s' % line 
    for listline in list:
        print listline 
        from_point = listline[1]['from'] 
        to_point = from_point + listline[1]['length'] 
    
        data = line[from_point:to_point]
        name = listline[0]
        print 'name: %s' % name 
        print 'Data: %s' % data 

    
        

print 'Closing file. EOP' 
f.close()
Die for listline in list: läuft gut weil er jetzt jedes einzelne
Listenelement erkennt. Allerdings kommt bei dieser Fehlermeldung:
data = line[from_point:to_point]
Und zwar weil die Werte von from oder lenght nicht integer sind.
Gut gibt man die Liste mit aus erhält man dies:

Code: Alles auswählen

[['NUMMER', {'length': '5', 'from': '99'}], ['NAME', {'length': '8', 'from': '104'}], ['SKZSICH', {'length': '3', 'from': '112'}], ['DATABR', {'length': '8', 'from': '115'}]]
die Werte von length und from stehen im Hocjkomma was ja fürn nen String
spricht.
Doch warum sind sie Strings?

MFG

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

Da werden die Zahlen wohl schon beim XML import als String importiert... Sind die in den XML Datei auch als Zahlen "ausgewiesen"???

Als workaround, könntest du sowas machen wie:

Code: Alles auswählen

try:
  item = int( item )
except:
  pass

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
TripleH
User
Beiträge: 29
Registriert: Donnerstag 11. Dezember 2003, 12:58

Hi,

Die Zahl steht in nem Tag. Denk mal wird wohl schon da nen String sein.
Dein Ansatzt fängt das aber nur ab oder? Doch wie bekomme ich hin das die Zahlen integer werden? Probier auch schon hin und her aber irgendwie läufts nicht.

MFG

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

Hallo,

So ich habs jetzt so:

Code: Alles auswählen

import xml.parsers.expat 
import MySQLdb 
list=[]
l =[]
class Reader:
    def read( self, filename ):
        self.query = '['
        self.path = [] 

        p = xml.parsers.expat.ParserCreate() 

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

        f = open("C:\\test.xml", 'r' ) 
        p.ParseFile( f ) 
        f.close() 

    def add_seperator( self ): 
        if not self.first_col: 
            self.query += ",\n " 
        else: 
            self.first_col = False 

    def start_element( self, name, attrs): 
        path = "/" . join( self.path ) 

        if path == 'Media': 
            if name == 'Table': 
                self.first_col = True 
        
       
        self.path.append( name ) 
        self.cur_data = '' 
    
    def end_element( self, name):
        path = "/" . join( self.path ) 
        
        
        if path == 'Media/Table/FixedLength/FixedColumn/Name': 
            self.add_seperator() 
            self.query += "['" + self.cur_data + "'," 
           
            self.n = self.cur_data.encode('latin-1')
            
        
           
        if path == 'Media/Table/FixedLength/FixedColumn/FixedRange/From':
            self.query += " {'from': " + self.cur_data + ","
            self.f = self.cur_data.encode('latin-1')
       
            

        if path == 'Media/Table/FixedLength/FixedColumn/FixedRange/Length':
            self.query += "'length': " + self.cur_data + "}]"
            print self.cur_data
            print'hier'
            print self.f
        
            list.append([self.n, {'from':int(self.f), 'length': int(self.cur_data.encode('latin-1'))}])
        if path == 'Media/Table': 
            self.query += "]" 
        
        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' ) 
spec = r.get_query().encode('latin-1') 
print spec
print list
print l     

f = file("C:\\test.txt", 'r')


for line in f:
    data = ''
    line = line.splitlines()[0]
    print 'Line: %s' % line
    for listline in list:
        print listline 
        from_point = listline[1]['from'] 
        to_point = from_point + listline[1]['length'] 
    
        data = data +"'"+line[from_point:to_point]+"',"
        name = listline[0]
        query = 'INSERT INTO der VALUES ('+ data+')'
        print query
    
    
        

print 'Closing file. EOP' 
f.close()
Das einzige Prob ist jetzt das der Query vernünftig wird.
Und zwar wird ja bei dem Create Vorgang deines andern Skriptes Progchild
automatisch der Name der TAbelle aus der xml Datei ermittelt und
dann über ne Variable in den Query eingefügt. In welcher Variablen
ist der gespeichert? Wie man sieht heißt jetz der Name der Tabelle der
und wurde manuell eingefügt von mir...(und dat ist Mist:)) Und gut das mit dem Komma nach dem
letzten Element habe ich auch noch. Das sind die 2 Sachen die ich nicht 100%
an deinem andern Skript verstanden habe (wo anhand der xml die Tabelle erstellt
wir)kannst du mir das nochmal erklären damit ichs hier auch so machen kann
und den Namen der Tabelle automatisch in den Query eingefügt wird.
Ich hoffe du verstehst mich.Glaub ich hab ganz schön undeutlich geschrieben:)

MFG

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

Der Name wird in keine Variable gespeichert, sondern nur in self.cur_data zwischengelagert.

In dem Teil meines Scriptes wirde der Name dem Query hinzugefügt.

Code: Alles auswählen

def end_element( self, name):
	path = "/" . join( self.path )
	if path == 'Media/Table/Name':
		self.query += self.cur_data + "\n(\n"

Du musst die also an der Stelle self.cur_data in eine Variable speichern...
Antworten