views:

631

answers:

4

Does anyone know of a good class to read in .ged files

Gedcom is a file format that is used to store genealogical information.

My goal is to write something that would let me import a ged file and export a .dot file for graphviz so that I can make a visual representation of a family tree

thanks if you can help

+1  A: 

I'd be fairly surprised if there was a C# reader for this format available on the web, given that it's a fairly specialized format. On the upside, the format looks to be pretty straightforward to read if you need to create your own reader. I would suggest going down that path and coming back to SO if you have specific questions about the implementation. Take a look at the System.IO.StreamReader class; it's trivial to read in a file line-by-line that way, and parsing the individual lines should be simple as well.

Good luck!

Adam Robinson
I know that's probably whats going to happen. I would like to avoid that if possible ( no need to re-invent the wheel).
Crash893
I think I may have a idea how I want to do this --- each individual is delimited. then each family is delimited with a pointer to the individuals that are involved.I think if just read that info in ill be fine. I do wish they would go xml like the rest of civilized formats.
Crash893
+3  A: 

I would actually have been surprised if there wasn't at least the beginnings of one. I found Gedcom.NET (sourceforge) quite easily

Matthew Flaschen
+1 for showing my small-mindedness ;)
Adam Robinson
I found that too. this could also be my complete lack experience but the class structure seems pretty complex.
Crash893
Would have been helpful to mention that in your question, and perhaps what you find complex. It's probably better to try to see if you can understand this (perhaps contact the author or ask another question here) than reinvent a simpler version that will gradually become more complex.
Matthew Flaschen
@Matthew Flaschen I found it after posting the question
Crash893
Ah, thanks for clarifying.
Matthew Flaschen
i found 15 errors when i doenloaded this project and tried to build it...
Radhi
A: 

Here is my first very very tentative step. your input would be greatly appertained.

One question i do have is there a way to test the next line using stream reader with out actually moving the "pointer" down to that line

I basically need to go from 0 node to 0 node (0 being the beginning of a clump of info not necessarily a family member it could be something about the document itself);

(I may try something with split now that i think of it)

struct indi
{
    public string ID;
    public string Name;
    public string Sex ;
    public string BirthDay;
    public bool Dead ;
    public string DeathDay;
    public string FamID;
}
List<indi> Individuals = new List<indi>();
private void button1_Click(object sender, EventArgs e)
{
    string path =@"C:\Document1.ged";
    StreamReader SR = new StreamReader(path);

    while (!SR.EndOfStream)
    {
        string Eval = SR.ReadLine();
        if(Eval.Contains('0'))
        {
            if (Eval.Contains("INDI"))
            {
                indi I = new indi();
                Eval = Eval.Replace(" INDI", "");
                Eval = Eval.Replace("@", "");
                Eval = Eval.Replace("0 ", "");
                I.ID = Eval;

                Individuals.Add(I);
            }
            else
            {
                //break;
            }




        }
    }
}

}

Crash893
+3  A: 

Heres my best attempt so far.

It seems to be working for what i need though its defiently not full proof ( then again my family tree is rather large and that adds some complexity)

please let me know if you think i could make anything more elequient

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;
        }
Crash893