xml-dateien

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
powerslide

Hallo,

ich bin gerade dabei python zu lernen.. mach ich aus spaß an der freud und wegen meinem praktikum..

und hier gehts auch direkt zu meinem problem..
ich bastel hier mit xml-dateien rum .. leider werden die einfach nur stumpfsinnig exportiert was zur folge hat das einige tags nicht html konform sind
bsp.:
<para>...</para> anstatt von <p>...</p>
<para class="heading1">...</para> anstatt von <p><b>...</b></p>

also hab ich mir gedacht ich schreib mir nen kleinen datei parser.
zuerst wird in einem verzeichnis sowie in allen unterverzeichnissen nach xml dateien gesucht.. funktioniert auch wunderbar.. diese dateien werden dann nacheinander an den filter übergeben.
der filter öffnet dann die datei und verarbeitet diese zeilenweise
und schreibt das dann eben in eine neue datei.
funktioniert eigentlich wunderbar...
für
<para>
</para>
das problem ist bei dem complexeren ausdruck
wenn ich zuerst <para> und </para> verarbeite verbaue ich mir natürlich die möglichkeit den bould-tag von der überschrift zu beenden
also hab ich mir gedacht.. suchst du erst nach der überschrift und taushct das aus.. und dann behandelst du die restlichen para-tags
suchen tu ich die ausdrücke folgendermaßen

Code: Alles auswählen

'.*?'
funktioniert auch

will ich das aber austauschen:

Code: Alles auswählen

        expr = re.sub ('', '', expr)
        code = "%(expr)s" % vars()
        text = re.sub (zu_ersetzen, code, text)
bricht er immer irgendwann ab und liefert folgenden traceback

Code: Alles auswählen

Traceback (most recent call last):
  File "<pyshell#10>", line 1, in -toplevel-
    convert()
  File "H:\My Projects\python\filereader_v13.py", line 27, in convert
    findfiles(pfad, '.xml')
  File "H:\My Projects\python\filereader_v13.py", line 22, in findfiles
    filter1(datei, newdat)
  File "H:\My Projects\python\filter.py", line 45, in filter1
    line = re.sub (zu_ersetzen, code, line)
  File "C:\Python24\lib\sre.py", line 142, in sub
    return _compile(pattern, 0).sub(repl, string, count)
  File "C:\Python24\lib\sre.py", line 227, in _compile
    raise error, v # invalid expression
error: unbalanced parenthesis
da ich zuerst die komplette datei auf einmal durchsucht habe dachte ich es liegt an der grösse (0,5MB und mehr)
also hab ich versucht dieses problem zu umgehen indem ich die datei zeilenweise einlese..
leider bricht das ganze genau an der selben stelle ab

so.. hier noch die verschiedenen filtervarianten die ich probiert habe:

Code: Alles auswählen

def filter3(infile, outfile):
    out = open(outfile, 'w')
    for line in open(infile):
        re.sub('(.+?)', r'\1', line)
        re.sub('(.*?)', r'', line)
        out.write(line)
    out.close()
        
def filter2(text):
    while 1:
        ort = re.search ('.*?', text)
        if ort == None:
            break
        zu_ersetzen = ort.group()
        expr = re.sub ('', '', expr)
        code = "%(expr)s" % vars()
        text = re.sub (zu_ersetzen, code, text)
    return text

def filter1(infile, outfile):
    out = open(outfile, 'w')
    for line in open(infile):
        while 1:
            ort = re.search ('.*?', line)
            if ort == None:
                break
            zu_ersetzen = ort.group()
            expr = re.sub ('', '', expr)
            code = "%(expr)s" % vars()
            line = re.sub (zu_ersetzen, code, line)
            out.write(line)
    out.close()
wäre super wenn mir wer auf die sprünge helfen könnte

greetz

slide
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Hi. Mach mal bitte das hier zusätzlich zum filter1 und führ es dann mal aus. Ich will wissen, was da eingesetzt wird, wenn er abbricht :wink:

Code: Alles auswählen

    try:
        text = re.sub (zu_ersetzen, code, text)
    except re.error:
        print repr(zu_ersetzen)
        print repr(code)
        print repr(text)
        raise
powerslide
User
Beiträge: 51
Registriert: Freitag 10. Dezember 2004, 09:05
Wohnort: Erlangen
Kontaktdaten:

moin...

ich hab das jetzt mal reingebastelt

also
zu_ersetzen = '<para class="heading3">a) SW-Komponente/SW-Modul beschreiben</para>'
code = '<p><b>a) SW-Komponente/SW-Modul beschreiben</b></p>'
tja und text ist der ursprüngliche text, weil er ja nichts ändert.
kann den aber nicht einfach so posten! wenn er unbedingt wichtig ist dann zensier ich ihn und poste dann.
Traceback (most recent call last):
File "<pyshell#2>", line 1, in -toplevel-
convert()
File "H:\My Projects\python\filereader_v13.py", line 34, in convert
findfiles(pfad, '.xml')
File "H:\My Projects\python\filereader_v13.py", line 28, in findfiles
filter3(line)
File "H:\My Projects\python\filter.py", line 38, in filter3
text = re.sub (zu_ersetzen, code, text)
File "C:\Python24\lib\sre.py", line 142, in sub
return _compile(pattern, 0).sub(repl, string, count)
File "C:\Python24\lib\sre.py", line 227, in _compile
raise error, v # invalid expression
error: unbalanced parenthesis
besten dank für die hilfe..

slide
How many people can read hex if only you and dead people can read hex?

There are 10 types of people in the world: Those who understand binary, and those who don't...
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Hi. Ist ja klar, dass das nicht funktioniert, da die Klammer von "a)" nicht escaped ist. Soll heißen, er vermutet einen Regulären Ausdruck mit Klammern (Gruppen) und dieser beginnt aber nie. Also gibts nen Fehler. Abhilfe schafft re.escape . Aber: das ganze geht wesentlich einfacher, indem du Python einfach gleich die Texte einsetzen lässt. Dafür musst du in deinen Ausdruck Gruppen mit einbauen:

Code: Alles auswählen

def filter1(infile, outfile):
    suchmuster=re.compile('<para class="heading.">(.*?)</para>',re.I)
    out = open(outfile, 'w') 
    for line in open(infile): 
        line=suchmuster.sub("<p><b>\\1</b></p>")
        out.write(line) 
    out.close()
powerslide
User
Beiträge: 51
Registriert: Freitag 10. Dezember 2004, 09:05
Wohnort: Erlangen
Kontaktdaten:

oh mann.. an die shice klammer hab ich gar nicht gedacht...

aber trotzdem mag das nich so wirklich.. aber macht ersma nix..

dafür hab ich ein anderes Problem..

und zwar such ich die strings [Q-] ,[PM-] und [role] und will diese einfach löschen .. sollte ja nicht so schwer sein also.. vor die eckigen klammern schon escapes davor.. trotzdem löscht er mir quasi alle zeichen die in dem string enthalten sind.. ich hab den ausdruck sogar ma an re.escape übergeben dann kam sowas bei raus \\[Q\\-\\]
aber das macht genau den selben fehler

btw ich poste ma meinen aktuellen code:

filter:

Code: Alles auswählen

# -*- coding: cp1252 -*-

import re

def f1(text):
    new_text = ''
    for i in range( len(text) ):
        if text[i] == '[':
            new_text = new_text + ''
        elif text[i] == ']':
            new_text = new_text + ''
        else:
            new_text = new_text + text[i]
    return new_text

def f2(text, old, new):
    while 1:
        ort = re.search (old, text)
        if ort == None:
            break
        zu_ersetzen = ort.group()
        code = new % vars()
        text = re.sub (zu_ersetzen, code, text)
    return text
der aufruf von der einzelnen filter:

Code: Alles auswählen

# -*- coding: iso-8859-15 -*-
#!/usr/bin/env python

def convert():

    import os
    import string
    import re
    import filter
    
    #pfad = input("Suchpfad > ")
    pfad = 'C:\Programme\Temix\XML'
    #pfad2 = 'H:\My Projects\output'
  
    def findfiles(path, extension, depth=0):
        for item in os.listdir(path):
            itemWithPath = os.path.join(path, item)
            if item.endswith(extension):
                print 'Datei '+ item +' wird eingelesen' # file name only
                datei = itemWithPath
                in_file = open(datei,"r")
                inhalt = in_file.read()
                in_file.close()
                new_string = str(inhalt)
                print 'starte Konvertierung'
                new_string = string.replace(new_string, '[Q-]', '')
                new_string = string.replace(new_string, '[PM-]', '')
                new_string = string.replace(new_string, '[role]', '')
                new_string = filter.f1(new_string)
                #new_string = filter.f2(new_string, '', '')
                #new_string = filter.f2(new_string, '', '')
                #new_string = filter.f2(new_string, '', '')
                print 'schreibe Datei'
                try:
                    out_file = open(datei, "w")    
                except IOError: # EAdateir
                    print 'Konnte Datei ' + datei + 'nicht öffnen!'
                out_file.write(new_string)
                out_file.close()
                print 'Datei konvertiert und geschrieben'
            if os.path.isdir(itemWithPath):
                findfiles(itemWithPath, extension, depth + 1)
        
    findfiles(pfad, '.xml')
    print 'Konvertierung abgeschlossen'
und der versuch deinen code zu integrieren:

Code: Alles auswählen

def filter3(text):
    while 1:
        ort = re.compile ('<para class="heading.">(.*?)</para>', re.I)
        if ort == None:
            break
        text = ort.sub ('</b>\\1</p>, text)
    return text
nomma fädd merci.. und greetz

slide
Zuletzt geändert von powerslide am Montag 13. Dezember 2004, 13:49, insgesamt 1-mal geändert.
How many people can read hex if only you and dead people can read hex?

There are 10 types of people in the world: Those who understand binary, and those who don't...
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Du verwendest ja quasi sieben mal die gleiche Funktion... Warum machst du nicht sowas:

Code: Alles auswählen

def filter(text, regex):
    while 1:
        ort = re.search (regex, text)
[...]

Code: Alles auswählen

[...]
new_string = filter(new_string, '\[Q-\]') 
new_string = filter(new_string, '\[PM-\]') 
[...]
powerslide
User
Beiträge: 51
Registriert: Freitag 10. Dezember 2004, 09:05
Wohnort: Erlangen
Kontaktdaten:

super idee...

hab ich mir auch schon gedanken gemacht wie ich das am geschickstesten lösen könnte.. und wollte das eigentlich per subpatternmatch realisieren..

allerdings hab ich dies .. weils ja nur codeverschönerung ist erstmal hinter die codefunktionalität geschoben..

weil dummerweise killt mir diese komische suchfunktion nach [Q-] alle '-' in der xml-datei .. egal wie oft ich diese [] escape *nerv*
How many people can read hex if only you and dead people can read hex?

There are 10 types of people in the world: Those who understand binary, and those who don't...
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

powerslide hat geschrieben:und zwar such ich die strings [Q-] ,[PM-] und [role] und will diese einfach löschen
Also das würde ich eigentlich nicht mit RE machen, sondern so:

Code: Alles auswählen

text = text.replace("[Q-]", "")
text = text.replace("[PM-]", "")
text = text.replace("[role]", "")
Mit RE müßte es aber auch direkt in einer Zeile gehen...
Irgendwas wie: "\\[(Q-|PM-|role)\\]"
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hiermit kann man ganz gut Regular Expressions testen:

Code: Alles auswählen

import re

text="blabla[Q-]eofjweof[PM-]wegweg[role]wgeweg"

def re_show(pat, s):
    print re.compile(pat, re.I).sub("\n->\g<fund><-\n", s.rstrip()),'\n'

re_show("\\[(?P<fund>Q-|PM-|role)\\]",text)
Ergebnis:

Code: Alles auswählen

blabla
->Q-<-
eofjweof
->PM-<-
wegweg
->role<-
wgeweg
Wie man jetzt aber dahin kommt, das die gefundenen Zeichen gelöscht werden, weiß ich leider jetzt auch nicht...
powerslide
User
Beiträge: 51
Registriert: Freitag 10. Dezember 2004, 09:05
Wohnort: Erlangen
Kontaktdaten:

super...

das mit dem einfachen string.replace hab ich in der doku voll +überlesen..
danke für den tip.. funktioniert einwandfrei!

jetzt nur noch das mit dem para class="heading... abfischen dann läufts so wie ich mir das vorstelle..
How many people can read hex if only you and dead people can read hex?

There are 10 types of people in the world: Those who understand binary, and those who don't...
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

powerslide hat geschrieben: <para>...</para> anstatt von <p>...</p>
<para class="heading1">...</para> anstatt von <p><b>...</b></p>
Naja, was ist hier mit der billig Lösung:

Code: Alles auswählen

ReplaceSettings={
    "<para>" : "<p>",
    "</par>" : "</p>",
    '<para class="heading1">': "<p><b>",
    "</para>" : "</b></p>"
}

for von, nach in ReplaceSettings.iteritems():
    text = text.replace( von,nach )
powerslide
User
Beiträge: 51
Registriert: Freitag 10. Dezember 2004, 09:05
Wohnort: Erlangen
Kontaktdaten:

so..

wahrscheinlich auch ziemlich billige lösung...

Code: Alles auswählen

# -*- coding: iso-8859-15 -*-
#!/usr/bin/env python

def convert():

    import os
    import string
    import re
    from time import sleep
    
    print 'Path must be enclosed with quotation marks'
    print 'e.g.: \'C:\Programme\TemiX\XML\''
    pfad = input("path > ")
    #pfad = 'C:\Programme\Temix\XML'
    

    def f1(text):
        new_text = ''
        for i in range( len(text) ):
            if text[i] == '[':
                new_text = new_text + ''
            elif text[i] == ']':
                new_text = new_text + ''
            else:
                new_text = new_text + text[i]
        return new_text

    def f2(text, old, new):
        while 1:
            ort = re.search (old, text)
            if ort == None:
                break
            zu_ersetzen = ort.group()
            code = new % vars()
            text = re.sub (zu_ersetzen, code, text)
        return text

    def f3(text):
        while 1:
            ort = re.search ('(.+?)', text)
            if ort == None:
                break
            text = re.sub('(.+?)', r'\1', text)
        return text     

  
    def findfiles(path, extension, depth=0):
        for item in os.listdir(path):
            itemWithPath = os.path.join(path, item)
            if item.endswith(extension):
                datei = itemWithPath
                print 'Starting conversion of '+ datei
                in_file = open(datei,"r")
                inhalt = in_file.read()
                in_file.close()
                new_string = str(inhalt)
                new_string = string.replace(new_string, '[Q-]', '')
                new_string = string.replace(new_string, '[PM-]', '')
                new_string = string.replace(new_string, '[role]', '')
                new_string = f1(new_string)
                new_string = f3(new_string)
                new_string = f2(new_string, '', '')
                new_string = f2(new_string, '', '')
                try:
                    out_file = open(datei, "w")    
                except IOError:
                    print 'File ' + datei + 'could not be opened!'
                out_file.write(new_string)
                out_file.close()
                print 'File ' + datei + ' converted and written'
            if os.path.isdir(itemWithPath):
                findfiles(itemWithPath, extension, depth + 1)
        
    findfiles(pfad, '.xml')
    print 'conversion done!'
    sleep(5)

if __name__ == '__main__':
    convert()
 
aber .. es funktioniert *froi*


nochmals danke .. für die hilfe.. war echt super..
und ich muss feststellen.. meine sozusagen erste begegnung mit python war sehr kewl.. denke ich verartsche nächstes semester die jungs an der uni und schreib meine klausur anstatt in c in python ....

slide
How many people can read hex if only you and dead people can read hex?

There are 10 types of people in the world: Those who understand binary, and those who don't...
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Noch was zum kürzen:

Code: Alles auswählen

text="abcdefg"

for i in range( len(text) ):
    print text[i]

print "="*30

for i in text:
    print i

Code: Alles auswählen

a
b
c
d
e
f
g
==============================
a
b
c
d
e
f
g
Ach und generell... Deine Funktion f1 macht doch nichts anderes als das hier:

Code: Alles auswählen

def f1(text):
    return text.replace("[","").replace("]","")
oder?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

powerslide hat geschrieben:und ich muss feststellen.. meine sozusagen erste begegnung mit python war sehr kewl.. denke ich verartsche nächstes semester die jungs an der uni und schreib meine klausur anstatt in c in python ....
In Informatik nutze ich auch Python statt Basic :)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten