有没有用Python写的GEDCOM解析器?

18 投票
6 回答
5277 浏览
提问于 2025-04-15 17:07

GEDCOM是一种用于交换家谱数据的标准。

我找到了一些用不同编程语言写的解析器:

但是到目前为止,我还没有找到用Python写的解析器。我找到的最接近的文件是libgedcom.py,这个文件来自GRAMPS项目,但里面充满了对GRAMPS模块的引用,让我觉得无法使用。

我只想要一个用Python写的简单独立的GEDCOM解析库。有没有这样的东西呢?

6 个回答

5

我知道这个讨论已经很久了,但我在搜索的时候找到了它,还有这个项目 https://github.com/madprime/python-gedcom/

这个代码非常干净,而且功能也很强大。

7

我从mwhite的回答中拿了一些代码,稍微扩展了一下(其实扩展得不少),然后把它放到了github上:http://github.com/dijxtra/simplepyged。如果你有其他想法或者建议想让我加的,欢迎告诉我 :-)

10

几年前,我在一个更大的项目中写了一个简单的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()

撰写回答