将 Gedcom 解析为 SQLite 数据库
Parse Gedcom to SQLite-Database
我是一名爱好 Xojo 用户。我想将 Gedcom 文件导入我的程序,特别是 SQLite 数据库。
数据库结构
表
人
- ID: Integer
- Gender: Varchar // M, F or U
- Surname: Varchar
- Givenname: Varchar
人际关系
- ID: Integer
- Husband: Integer
- Wife: Integer
儿童
- ID: Integer
- PersonID: Integer
- FamilyID: Integer
- Order: Integer
人物事件
- ID: Integer
- PersonID: Integer
- EventType: Varchar // e.g. BIRT, DEAT, BURI, CHR
- Date: Varchar
- Description: Varchar
- Order: Integer
关系事件
- ID: Integer
- RelationshipID: Integer
- EventType: Varchar // e.g. MARR, DIV, DIVF
- Date: Varchar
- Description: Integer
- Order: Integer
我写了一个可以工作的 Gedcom-Line-Parser。他将单个 Gedcomline 拆分为:
- Level As Integer
- Reference As String // optional
- Tag As String
- Value As String // optional
我通过 TextInputStream 加载 Gedcom 文件(工作正常)。不,我需要解析每一行。
Gedcom-个人样本
0 @I1@ INDI
1 NAME George /Clooney/
2 GIVN George
2 SURN Clooney
1 BIRT
2 DATE 6 MAY 1961
2 PLAC Lexington, Fayette County, Kentucky, USA
你会看到,Level-Numbers 向我们展示了 "Tree-Structure"。所以我认为将文件解析为分离的对象(PersonObj、RelationshipObj、EventObj 等)到 JSONItem 中是最好和最简单的方法,因为它很容易获得节点的 Childs。稍后,我可以简单地读取节点、子节点来创建数据库条目。但是我不知道如何创建这样的算法。
有人可以帮我吗?
要快速解析 Gedcom 行,请尝试以下想法:
将整个文件读入一个字符串并将行拆分:
dim f as FolderItem = ...
dim fileContent as String = TextInputStream.Open(f).ReadAll
fileContent = fileContent.DefineEncoding (Encodings.WindowsLatin1)
dim lines() as String = ReplaceLineEndings(fileContent,EndOfLine).Split(EndOfLine)
使用 RegEx 解析每一行以提取其 3 列
dim re as new RegEx
re.SearchPattern = "^(\d+) ([^ ]+)(.*)$"
for each line as String in lines
dim rm as RegExMatch = re.Search (line)
if rm = nil then
// nothing found in this line. Is this correct?
break
continue // -> onward with next line
end
dim level as Integer = rm.SubExpressionString(1).Val
dim code as String = rm.SubExpressionString(2)
dim value as String = rm.SubExpressionString(3).Trim
... process the level, code and value
next
RegEx 搜索模式意味着它会查找行的开头 ("^"),然后查找一个或多个数字 ("\d")、一个空白、一个或多个非空白字符 (" [^ ]"),最后是字符串结尾 ("$") 之前的任何更多字符 (".")。每个组周围的括号是为了使用 SubExpression() 提取它们的结果。
只要该行不包含至少一个数字、一个空格和至少一个字符,rm = nil 的检查就会命中。如果 Gedcom 文件格式不正确或有空行,则可能是这种情况。
希望对您有所帮助。
我是一名爱好 Xojo 用户。我想将 Gedcom 文件导入我的程序,特别是 SQLite 数据库。
数据库结构
表
人
- ID: Integer
- Gender: Varchar // M, F or U
- Surname: Varchar
- Givenname: Varchar
人际关系
- ID: Integer
- Husband: Integer
- Wife: Integer
儿童
- ID: Integer
- PersonID: Integer
- FamilyID: Integer
- Order: Integer
人物事件
- ID: Integer
- PersonID: Integer
- EventType: Varchar // e.g. BIRT, DEAT, BURI, CHR
- Date: Varchar
- Description: Varchar
- Order: Integer
关系事件
- ID: Integer
- RelationshipID: Integer
- EventType: Varchar // e.g. MARR, DIV, DIVF
- Date: Varchar
- Description: Integer
- Order: Integer
我写了一个可以工作的 Gedcom-Line-Parser。他将单个 Gedcomline 拆分为:
- Level As Integer
- Reference As String // optional
- Tag As String
- Value As String // optional
我通过 TextInputStream 加载 Gedcom 文件(工作正常)。不,我需要解析每一行。
Gedcom-个人样本
0 @I1@ INDI
1 NAME George /Clooney/
2 GIVN George
2 SURN Clooney
1 BIRT
2 DATE 6 MAY 1961
2 PLAC Lexington, Fayette County, Kentucky, USA
你会看到,Level-Numbers 向我们展示了 "Tree-Structure"。所以我认为将文件解析为分离的对象(PersonObj、RelationshipObj、EventObj 等)到 JSONItem 中是最好和最简单的方法,因为它很容易获得节点的 Childs。稍后,我可以简单地读取节点、子节点来创建数据库条目。但是我不知道如何创建这样的算法。
有人可以帮我吗?
要快速解析 Gedcom 行,请尝试以下想法:
将整个文件读入一个字符串并将行拆分:
dim f as FolderItem = ...
dim fileContent as String = TextInputStream.Open(f).ReadAll
fileContent = fileContent.DefineEncoding (Encodings.WindowsLatin1)
dim lines() as String = ReplaceLineEndings(fileContent,EndOfLine).Split(EndOfLine)
使用 RegEx 解析每一行以提取其 3 列
dim re as new RegEx
re.SearchPattern = "^(\d+) ([^ ]+)(.*)$"
for each line as String in lines
dim rm as RegExMatch = re.Search (line)
if rm = nil then
// nothing found in this line. Is this correct?
break
continue // -> onward with next line
end
dim level as Integer = rm.SubExpressionString(1).Val
dim code as String = rm.SubExpressionString(2)
dim value as String = rm.SubExpressionString(3).Trim
... process the level, code and value
next
RegEx 搜索模式意味着它会查找行的开头 ("^"),然后查找一个或多个数字 ("\d")、一个空白、一个或多个非空白字符 (" [^ ]"),最后是字符串结尾 ("$") 之前的任何更多字符 (".")。每个组周围的括号是为了使用 SubExpression() 提取它们的结果。
只要该行不包含至少一个数字、一个空格和至少一个字符,rm = nil 的检查就会命中。如果 Gedcom 文件格式不正确或有空行,则可能是这种情况。
希望对您有所帮助。