2009-12-17 25 views
16

GEDCOM ist ein Standard für den Austausch genealogischer Daten.Gibt es in Python einen GEDCOM-Parser?

Ich habe festgestellt Parser in

geschrieben

aber nicht so weit in Python geschrieben. Der nächste, den ich habe, ist die Datei libgedcom.py aus dem GRAMPS-Projekt, aber das ist so voll mit Referenzen auf GRAMPS-Module, dass sie für mich nicht brauchbar sind.

Ich möchte nur eine einfache eigenständige GEDCOM-Parser-Bibliothek in Python geschrieben. Gibt es das?

Antwort

8

Vor ein paar Jahren schrieb ich einen einfachen GEDCOM zu XML-Übersetzer in Python als Teil einer larger project. Ich fand, dass der Umgang mit den GEDCOM-Daten im XML-Format viel einfacher war (besonders, wenn der nächste Schritt XSLT beinhaltete).

Ich habe den Code im Moment nicht online, also habe ich das Modul in diese Nachricht eingefügt. Das funktioniert für mich; keine Garantien. Hoffe das hilft aber.

import codecs, os, re, sys 
from xml.sax.saxutils import escape 

fn = sys.argv[1] 

ged = codecs.open(fn, encoding="cp437") 
xml = codecs.open(fn+".xml", "w", "utf8") 
xml.write("""<?xml version="1.0"?>\n""") 
xml.write("<gedcom>") 
sub = [] 
for s in ged: 
    s = s.strip() 
    m = re.match(r"(\d+) (@(\w+)@)?(\w+)((.*))?", s) 
    if m is None: 
     print "Error: unmatched line:", s 
    level = int(m.group(1)) 
    id = m.group(3) 
    tag = m.group(4) 
    data = m.group(6) 
    while len(sub) > level: 
     xml.write("</%s>\n" % (sub[-1])) 
     sub.pop() 
    if level != len(sub): 
     print "Error: unexpected level:", s 
    sub += [tag] 
    if id is not None: 
     xml.write("<%s id=\"%s\">" % (tag, id)) 
    else: 
     xml.write("<%s>" % (tag)) 
    if data is not None: 
     m = re.match(r"@(\w+)@", data) 
     if m: 
      xml.write(m.group(1)) 
     elif tag == "NAME": 
      m = re.match(r"(.*?)/(.*?)/$", data) 
      if m: 
       xml.write("<forename>%s</forename><surname>%s</surname>" % (escape(m.group(1).strip()), escape(m.group(2)))) 
      else: 
       xml.write(escape(data)) 
     elif tag == "DATE": 
      m = re.match(r"(((\d+)?\s+)?(\w+)?\s+)?(\d{3,})", data) 
      if m: 
       if m.group(3) is not None: 
        xml.write("<day>%s</day><month>%s</month><year>%s</year>" % (m.group(3), m.group(4), m.group(5))) 
       elif m.group(4) is not None: 
        xml.write("<month>%s</month><year>%s</year>" % (m.group(4), m.group(5))) 
       else: 
        xml.write("<year>%s</year>" % m.group(5)) 
      else: 
       xml.write(escape(data)) 
     else: 
      xml.write(escape(data)) 
while len(sub) > 0: 
    xml.write("</%s>" % sub[-1]) 
    sub.pop() 
xml.write("</gedcom>\n") 
ged.close() 
xml.close() 
1

Sie könnten das Tool SWIG verwenden, um C-Bibliotheken über die Oberfläche der nativen Sprache einzuschließen. Innerhalb von Python müssen Sie gegen die C API vorgehen, aber der Rest Ihres Codes kann nur Python sein.

Kann ein bisschen entmutigend klingen, aber sobald Sie Sache Einstellung erhalten, wird das Verwenden der zwei zusammen nicht schlecht sein. Es kann einige Macken geben, abhängig davon, wie die C-Bibliothek geschrieben wurde, aber Sie müssten sich mit einigen befassen, egal welche Option Sie verwendet haben.

+0

oder benutzen ctypes oder Cython (von Pyrex gegabelt). –

7

verknüpft ist I-Code von mwhite Antwort genommen haben, es erweitert ein bisschen (OK, mehr als nur ein bisschen) und bei Github veröffentlicht: http://github.com/dijxtra/simplepyged. Ich nehme Vorschläge, was sonst hinzuzufügen :-)

-1

Ein weiterer Grund-Parser für die GEDCOM 5.5 Format: https://github.com/rootsdev/python-gedcom-parser

+0

Bitte posten Sie keine Antworten zu off-topic Fragen! [Siehe: ** Sollte jemand zu off-topic Fragen beraten? **] (http://meta.stackoverflow.com/q/276572/1768232) Off-topic Fragen können geschlossen und gelöscht werden, was Ihren Beitrag zunichte machen könnte. Hier stellt sich die Frage nach einer Offsite-Ressource und ist auf dem Weg zur Schließung. –

Verwandte Themen