2009-12-17 28 views
16

GEDCOM là một tiêu chuẩn để trao đổi dữ liệu phả hệ.Có trình phân tích cú pháp GEDCOM được viết bằng Python không?

parsers tôi đã tìm thấy bằng văn bản trong

nhưng không ai cho đến nay được viết bằng Python. Gần nhất tôi đã đến là tập tin libgedcom.py từ dự án GRAMPS, nhưng đó là đầy đủ các tham chiếu đến các mô-đun GRAMPS như không thể sử dụng được cho tôi.

Tôi chỉ muốn một thư viện phân tích cú pháp độc lập GEDCOM được viết bằng Python. Điều này có tồn tại không?

Trả lời

8

Một vài năm trước, tôi đã viết GEDCOM đơn giản cho trình dịch XML trong Python như một phần của larger project. Tôi thấy rằng việc xử lý dữ liệu GEDCOM ở định dạng XML dễ dàng hơn nhiều (đặc biệt là khi bước tiếp theo liên quan đến XSLT).

Tôi không có mã trực tuyến tại thời điểm này, vì vậy tôi đã dán mô-đun vào thư này. Điều này làm việc cho tôi; không đảm bảo. Hy vọng điều này sẽ giúp mặc dù.

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

Bạn có thể sử dụng công cụ SWIG để bao gồm thư viện C mặc dù giao diện ngôn ngữ gốc. Bạn sẽ phải thực hiện các cuộc gọi chống lại api C từ bên trong Python, nhưng phần còn lại của mã của bạn chỉ có thể là Python.

Có thể âm thanh hơi khó khăn, nhưng một khi bạn có được thiết lập điều, sử dụng cả hai cùng nhau sẽ không xấu. Có thể có một số quirks tùy thuộc vào cách thư viện C được viết, nhưng bạn sẽ phải đối phó với một số không có vấn đề tùy chọn mà bạn sử dụng.

+0

Hoặc sử dụng ctypes hoặc Cython (chia hai từ Pyrex). –

7

Tôi đã lấy mã từ câu trả lời mwhite của, mở rộng nó một chút (OK, nhiều hơn chỉ là một chút) và niêm yết tại github: http://github.com/dijxtra/simplepyged. Tôi đưa các đề xuất về những gì khác để thêm :-)

-1

Một phân tích cú pháp cơ bản để định dạng GEDCOM 5.5: https://github.com/rootsdev/python-gedcom-parser

+0

Vui lòng không đăng câu trả lời cho các câu hỏi rõ ràng về chủ đề! [Xem: ** Có nên tư vấn về các câu hỏi về chủ đề không? **] (http://meta.stackoverflow.com/q/276572/1768232) Các câu hỏi ngoài chủ đề có thể bị đóng và xóa, điều này có thể vô hiệu hóa đóng góp của bạn. Ở đây, câu hỏi là yêu cầu một nguồn tài nguyên ngoài trang web và đang trên đường đóng cửa. –

Các vấn đề liên quan