Вопрос

Кто-нибудь знает хороший класс для чтения в файлах .ged

Gedcom - это формат файла, который используется для хранения генеалогической информации.

Моя цель - написать что-то, что позволило бы мне импортировать ged-файл и экспортировать файл .dot для graphviz, чтобы я мог визуально представить семейное древо

спасибо, если вы можете помочь

Это было полезно?

Решение

Вот моя лучшая попытка на данный момент.

Кажется, он работает для того, что мне нужно, хотя это явно не полное доказательство (опять же, мое генеалогическое дерево довольно большое, и это добавляет сложности)

, пожалуйста, дайте мне знать, если вы думаете, я мог бы сделать что-нибудь более изящное

struct INDI
        {
            public string ID;
            public string Name;
            public string Sex;
            public string BirthDay;
            public bool Dead;


        }
        struct FAM
        {
            public string FamID;
            public string type;
            public string IndiID;
        }
        List<INDI> Individuals = new List<INDI>();
        List<FAM> Family = new List<FAM>();
        private void button1_Click(object sender, EventArgs e)
        {
            string path = @"C:\mostrecent.ged";
            ParseGedcom(path);
        }

        private void ParseGedcom(string path)
        {
            //Open path to GED file
            StreamReader SR = new StreamReader(path);

            //Read entire block and then plit on 0 @ for individuals and familys (no other info is needed for this instance)
            string[] Holder = SR.ReadToEnd().Replace("0 @", "\u0646").Split('\u0646');

            //For each new cell in the holder array look for Individuals and familys
            foreach (string Node in Holder)
            {

                //Sub Split the string on the returns to get a true block of info
                string[] SubNode = Node.Replace("\r\n", "\r").Split('\r');
                //If a individual is found
                if (SubNode[0].Contains("INDI"))
                {
                    //Create new Structure
                    INDI I = new INDI();
                    //Add the ID number and remove extra formating
                    I.ID = SubNode[0].Replace("@", "").Replace(" INDI", "").Trim();
                    //Find the name remove extra formating for last name
                    I.Name = SubNode[FindIndexinArray(SubNode, "NAME")].Replace("1 NAME", "").Replace("/", "").Trim(); 
                    //Find Sex and remove extra formating
                    I.Sex = SubNode[FindIndexinArray(SubNode, "SEX")].Replace("1 SEX ", "").Trim();

                    //Deterine if there is a brithday -1 means no
                    if (FindIndexinArray(SubNode, "1 BIRT ") != -1)
                    {
                        // add birthday to Struct 
                        I.BirthDay = SubNode[FindIndexinArray(SubNode, "1 BIRT ") + 1].Replace("2 DATE ", "").Trim();
                    }

                    // deterimin if there is a death tag will return -1 if not found
                    if (FindIndexinArray(SubNode, "1 DEAT ") != -1)
                    {
                        //convert Y or N to true or false ( defaults to False so no need to change unless Y is found.
                        if (SubNode[FindIndexinArray(SubNode, "1 DEAT ")].Replace("1 DEAT ", "").Trim() == "Y")
                        {
                            //set death
                            I.Dead = true;
                        }
                    }
                    //add the Struct to the list for later use
                    Individuals.Add(I);
                }

                // Start Family section
                else if (SubNode[0].Contains("FAM"))
                {
                    //grab Fam id from node early on to keep from doing it over and over
                    string FamID = SubNode[0].Replace("@ FAM", "");

                    // Multiple children can exist for each family so this section had to be a bit more dynaimic

                    // Look at each line of node
                    foreach (string Line in SubNode)
                    {
                        // If node is HUSB
                        if (Line.Contains("1 HUSB "))
                        {

                            FAM F = new FAM();
                            F.FamID = FamID;
                            F.type = "PAR";
                            F.IndiID = Line.Replace("1 HUSB ", "").Replace("@","").Trim();
                            Family.Add(F);
                        }
                            //If node for Wife
                        else if (Line.Contains("1 WIFE "))
                        {
                            FAM F = new FAM();
                            F.FamID = FamID;
                            F.type = "PAR";
                            F.IndiID = Line.Replace("1 WIFE ", "").Replace("@", "").Trim();
                            Family.Add(F);
                        }
                            //if node for multi children
                        else if (Line.Contains("1 CHIL "))
                        {
                            FAM F = new FAM();
                             F.FamID = FamID;
                            F.type = "CHIL";
                            F.IndiID = Line.Replace("1 CHIL ", "").Replace("@", "");
                            Family.Add(F);
                        }
                    }
                }
            }
        }

        private int FindIndexinArray(string[] Arr, string search)
        {
            int Val = -1;
            for (int i = 0; i < Arr.Length; i++)
            {
                if (Arr[i].Contains(search))
                {
                    Val = i;
                }
            }
            return Val;
        }

Другие советы

В Codeplex есть очень симпатичный: FamilyShow (демонстрация WPF). Он импортирует / экспортирует GEDCOM 5.5 и имеет источник.

Я бы на самом деле был удивлен, если бы не было хотя бы одного начала. Я нашел Gedcom.NET ( sourceforge ) довольно легко

Я был бы весьма удивлен, если бы в Интернете был доступен читатель C # для этого формата, учитывая, что это довольно специализированный формат. С другой стороны, формат выглядит довольно простым для чтения, если вам нужно создать свой собственный ридер. Я бы предложил пойти по этому пути и вернуться к SO, если у вас есть конкретные вопросы по реализации. Посмотрите на класс System.IO.StreamReader ; Таким способом тривиально прочитать файл в строке, и анализ отдельных строк также должен быть простым.

Удачи!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top