Alcuni anni fa ho scritto un semplicistico convertitore da GEDCOM a XML in Python come parte di larger project. Ho scoperto che trattare i dati GEDCOM in un formato XML era molto più facile (specialmente quando il passo successivo riguardava XSLT).
Non ho il codice online al momento, quindi ho incollato il modulo in questo messaggio. Questo funziona per me; nessuna garanzia. Spero che questo aiuti però.
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()
fonte
2010-01-25 23:55:15
o utilizzare ctypes o Cython (biforcuta da Pyrex). –