Подтвердить что ты не робот

Есть ли GEDCOM-анализатор, написанный на Python?

GEDCOM - это стандарт для обмена генеалогическими данными.

Я нашел парсеров, написанных в

но пока ничего не написано на Python. Ближе всего я пришел к файлу libgedcom.py из проекта GRAMPS, но он так полон ссылок на модули GRAMPS, что не может быть полезен для меня.

Мне просто нужна простая автономная библиотека парсеров GEDCOM, написанная на Python. Это существует?

4b9b3361

Ответ 1

Несколько лет назад я написал упрощенный XML-переводчик GEDCOM для XML в Python как часть более крупного проекта . Я обнаружил, что обработка данных GEDCOM в формате XML была намного проще (особенно, когда следующий шаг включал XSLT).

У меня нет кода онлайн в данный момент, поэтому я вставлял модуль в это сообщение. Это работает для меня; нет гарантий. Надеюсь, что это поможет.

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()

Ответ 2

Я взял код из ответа mwhite, немного расширил его (ОК, больше, чем просто) и опубликовал в github: http://github.com/dijxtra/simplepyged. Я принимаю предложения о том, что еще добавить: -)

Ответ 3

Я знаю, что этот поток довольно старый, но я нашел его в моих поисках, а также этот проект https://github.com/madprime/python-gedcom/

Источник сжатый и очень функциональный.

Ответ 5

Вы можете использовать инструмент SWIG для включения библиотек C, хотя интерфейс на родном языке. Вы должны будете делать вызовы против C api из Python, но остальная часть вашего кода может быть только Python.

Может показаться немного сложным, но как только вы получите настройку, использование двух вместе не будет плохой. Могут быть некоторые причуды, зависящие от того, как была написана библиотека C, но вам придется иметь дело с некоторыми независимо от того, какой вариант вы использовали.