18

GEDCOM 是交换家谱数据的标准。

我发现了用

但到目前为止还没有一个用 Python 编写的。我最接近的是来自 GRAMPS 项目的 libgedcom.py 文件但它充满了对 GRAMPS 模块的引用,以至于我无法使用。

我只想要一个用 Python 编写的简单的独立 GEDCOM 解析器库。这存在吗?

4

6 回答 6

10

几年前,作为一个更大项目的一部分,我用 Python 编写了一个简单的 GEDCOM 到 XML 转换器。我发现以 XML 格式处理 GEDCOM 数据要容易得多(尤其是当下一步涉及 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()
于 2010-01-25T23:55:15.380 回答
7

我从 mwhite 的答案中获取了代码,对其进行了一些扩展(好的,不仅仅是一点)并发布在 github 上:http: //github.com/dijxtra/simplepyged。我接受关于还需要添加什么的建议:-)

于 2010-10-18T16:54:33.223 回答
5

我知道这个线程很老了,但我在搜索和这个项目中找到了它https://github.com/madprime/python-gedcom/

来源非常干净,非常实用。

于 2014-12-18T23:49:33.793 回答
2

Python 中的通用 GEDCOM 解析器链接自http://ilab.cs.byu.edu/cs460/2006w/assignments/program1.html

于 2010-06-22T18:46:19.260 回答
1

您可以使用SWIG工具通过本机语言界面包含 C 库。您必须从 Python 中调用 C api,但其余代码只能是 Python。

可能听起来有点令人生畏,但一旦你完成了设置,将两者结合使用不会是一件坏事。根据 C 库的编写方式,可能会有一些怪癖,但无论您使用哪个选项,您都必须处理一些问题。

于 2009-12-17T05:31:00.410 回答
0

GEDCOM 5.5 格式的另一个基本解析器:https ://github.com/rootsdev/python-gedcom-parser

于 2016-03-07T11:42:49.557 回答