Разбор Gedcom для SQLite-базы данных

Я Хобби 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

PersonEvents

 - ID: Integer
 - PersonID: Integer
 - EventType: Varchar // e.g. BIRT, DEAT, BURI, CHR
 - Date: Varchar
 - Description: Varchar
 - Order: Integer

RelationshipEvents

 - 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

Я загружаю Gedcom-файл через TextInputStream (работает нормально). Нет, мне нужно разобрать каждую строку.

Gedcom-Индивидуально-Sample

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

Как видите, номера уровней показывают нам "древовидную структуру". Поэтому я подумал, что это будет лучший и самый простой способ разбить файл на отдельные объекты (PersonObj, RelationshipObj, EventObj и т. Д.) В JSONItem, потому что там легко получить дочерние элементы узла. Позже я могу просто читать узлы, дочерние узлы, чтобы создавать записи базы данных. Но я не знаю, как создать такой алгоритм.

Кто-нибудь может помочь, пожалуйста?

1 ответ

Решение

Чтобы проанализировать линии 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 искажен или имеет пустые строки, это может иметь место.

Надеюсь это поможет.

Другие вопросы по тегам