2009-12-17 16 views
16

GEDCOM es un estándar para el intercambio de datos genealógicos.¿Hay un analizador GEDCOM escrito en Python?

analizadores que he hallado escrito en

pero ninguno hasta ahora escritos en Python. Lo más cerca que he llegado es el archivo libgedcom.py del proyecto GRAMPS, pero está tan lleno de referencias a los módulos de GRAMPS que no se pueden usar para mí.

Solo quiero una biblioteca de analizador GEDCOM independiente y simple escrita en Python. ¿Existe esto?

Respuesta

8

Hace algunos años escribí un traductor simplificado de GEDCOM a XML en Python como parte de un larger project. Descubrí que lidiar con los datos de GEDCOM en formato XML era mucho más fácil (especialmente cuando el siguiente paso involucraba a XSLT).

No tengo el código en línea en este momento, así que he pegado el módulo en este mensaje. Esto funciona para mí; sin garantías Espero que esto ayude sin embargo.

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

Puede usar la herramienta SWIG para incluir bibliotecas C a través de la interfaz de idioma nativo. Tendrás que hacer llamadas en contra de la api de C desde Python, pero el resto de tu código solo puede ser de Python.

Puede sonar un poco desalentador, pero una vez que haya configurado la cosa, usar los dos juntos no será malo. Puede haber algunas peculiaridades dependiendo de cómo se escribió la biblioteca C, pero tendría que lidiar con algunas, sin importar qué opción usara.

+0

o uso ctypes o Cython (en forma de horquilla de Pyrex). –

-1

Otro programa de análisis básico para el formato GEDCOM 5.5: https://github.com/rootsdev/python-gedcom-parser

+0

¡No publique respuestas a preguntas obviamente fuera del tema! [Ver: ** ¿Debería uno asesorar sobre preguntas fuera del tema? **] (http://meta.stackoverflow.com/q/276572/1768232) Las preguntas fuera del tema se pueden cerrar y eliminar, lo que podría anular su contribución. Aquí, la pregunta es pedir un recurso externo y está en camino hacia el cierre. –

Cuestiones relacionadas