<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <id>tag:www.refactormycode.com,2007:users1505</id>
  <link type="application/atom+xml" href="http://www.refactormycode.com/users/1505" rel="self"/>
  <title>crash893.myopenid.com</title>
  <updated>Thu May 14 19:42:07 -0700 2009</updated>
  <entry>
    <id>tag:www.refactormycode.com,2007:Code873</id>
    <published>2009-05-14T19:42:07-07:00</published>
    <updated>2011-04-23T07:38:53-07:00</updated>
    <title>[C#] Gedcom Reader</title>
    <content type="html">&lt;p&gt;Created this reader class for gedcom files ( genealogy format) the format is a flat ASCII file (that sucks) and i return a list of individuals and a list of family info&lt;/p&gt;

&lt;p&gt;I'm still fairly new at creating classes ( this is my first real on my own not for answer in a book class)&lt;/p&gt;

&lt;p&gt;EDIT:&lt;/p&gt;

&lt;p&gt;Someone suggested using seperate classes for the two structures i would be interested if you agree.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;pre&gt;## C# [C#]
using System.Collections.Generic;
using System.IO;

namespace GedcomReader
{

    class Gedcom
    {
        private string GedcomText = &amp;quot;&amp;quot;;


        public struct INDI
        {
            public string ID;
            public string Name;
            public string Sex;
            public string BDay;
            public bool Dead;
            public string FamS;
            public string FamC;
        }
        public struct FAM
        {
            public string FamID;
            public string Type;
            public string IndiID;
        }

        public List&amp;lt;INDI&amp;gt; Individuals = new List&amp;lt;INDI&amp;gt;();
        public List&amp;lt;FAM&amp;gt; Families = new List&amp;lt;FAM&amp;gt;();


        public Gedcom(string fileName)
        {
                //reads in the file as a block of text
            using (StreamReader SR = new StreamReader(fileName))
            {
                GedcomText = SR.ReadToEnd();
            }
            ReadGedcom();

        }

        private void ReadGedcom()
        {
            //Replaces &amp;quot;0 @&amp;quot; with an abratray char then splits on it to get the diffrent nodes of the gedcom file
            string[] Nodes = GedcomText.Replace(&amp;quot;0 @&amp;quot;, &amp;quot;\u0646&amp;quot;).Split('\u0646'); 

            foreach (string Node in Nodes) //searched though the nodes to see what type they are
            {
                string[] SubNode = Node.Replace(&amp;quot;\r\n&amp;quot;, &amp;quot;\r&amp;quot;).Split('\r'); 
                if (SubNode[0].Contains(&amp;quot;INDI&amp;quot;))  // im currently only intrested in the indi (individual) tag and the fam(family) tag all others get thrown out.
                {
                    Individuals.Add(ExtractINDI(SubNode));  
                }
                else if (SubNode[0].Contains(&amp;quot;FAM&amp;quot;))
                {
                    Families.Add(ExtractFAM(SubNode));
                }
            }
        }
        
        private FAM ExtractFAM(string[] Node)
        {
            string sFID = Node[0].Replace(&amp;quot;@ FAM&amp;quot;, &amp;quot;&amp;quot;);
            string sID = &amp;quot;&amp;quot;;
            string sType = &amp;quot;&amp;quot;;
            foreach (string Line in Node)
            {
                // If node is HUSB
                if (Line.Contains(&amp;quot;1 HUSB &amp;quot;))
                {
                    sType = &amp;quot;PAR&amp;quot;;
                    sID = Line.Replace(&amp;quot;1 HUSB &amp;quot;, &amp;quot;&amp;quot;).Replace(&amp;quot;@&amp;quot;, &amp;quot;&amp;quot;).Trim();
                }
                //If node for Wife
                else if (Line.Contains(&amp;quot;1 WIFE &amp;quot;))
                {
                    sType = &amp;quot;PAR&amp;quot;;
                    sID = Line.Replace(&amp;quot;1 WIFE &amp;quot;, &amp;quot;&amp;quot;).Replace(&amp;quot;@&amp;quot;, &amp;quot;&amp;quot;).Trim();
                }
                //if node for multi children
                else if (Line.Contains(&amp;quot;1 CHIL &amp;quot;))
                {
                    sType = &amp;quot;CHIL&amp;quot;;
                    sID = Line.Replace(&amp;quot;1 CHIL &amp;quot;, &amp;quot;&amp;quot;).Replace(&amp;quot;@&amp;quot;, &amp;quot;&amp;quot;);
                }
            }
            FAM Fam = new FAM();
            Fam.FamID = sFID;
            Fam.Type = sType;
            Fam.IndiID = sID;

            return Fam;
        }
        private INDI ExtractINDI(string[] Node)
        {
           //string[] SubNode = Node.Replace(&amp;quot;\r\n&amp;quot;, &amp;quot;\r&amp;quot;).Split('\r');
            //If a individual is found
            INDI I = new INDI();
            //Individual I = new Individual();
            if (Node[0].Contains(&amp;quot;INDI&amp;quot;))
            {
                //Create new Structure
                
                //Add the ID number and remove extra formating
                I.ID = Node[0].Replace(&amp;quot;@&amp;quot;, &amp;quot;&amp;quot;).Replace(&amp;quot; INDI&amp;quot;, &amp;quot;&amp;quot;).Trim();
                //Find the name remove extra formating for last name
                I.Name = Node[FindIndexinArray(Node, &amp;quot;NAME&amp;quot;)].Replace(&amp;quot;1 NAME&amp;quot;, &amp;quot;&amp;quot;).Replace(&amp;quot;/&amp;quot;, &amp;quot;&amp;quot;).Trim();
                //Find Sex and remove extra formating
                I.Sex = Node[FindIndexinArray(Node, &amp;quot;SEX&amp;quot;)].Replace(&amp;quot;1 SEX &amp;quot;, &amp;quot;&amp;quot;).Trim();

                //Deterine if there is a brithday -1 means no
                int BirthTest =FindIndexinArray(Node, &amp;quot;1 BIRT &amp;quot;);
                if (BirthTest != -1)
                {
                    // add birthday to Struct 
                    I.BDay = Node[BirthTest + 1].Replace(&amp;quot;2 DATE &amp;quot;, &amp;quot;&amp;quot;).Trim();
                }

                // deterimin if there is a death tag will return -1 if not found
                
                int DeathTest = FindIndexinArray(Node, &amp;quot;1 DEAT &amp;quot;);
                if (DeathTest != -1)
                {
                    //convert Y or N to true or false ( defaults to False so no need to change unless Y is found.
                    if (Node[DeathTest].Replace(&amp;quot;1 DEAT &amp;quot;, &amp;quot;&amp;quot;).Trim() == &amp;quot;Y&amp;quot;)
                    {
                        //set death
                        I.Dead = true;
                    }
                }
                int FamsTest = FindIndexinArray(Node, &amp;quot;1 FAMS &amp;quot;);
                if (FamsTest != -1)
                {
                    I.FamS = Node[FamsTest].Replace(&amp;quot;1 FAMS &amp;quot;,&amp;quot;&amp;quot;).Replace(&amp;quot;@&amp;quot;, &amp;quot;&amp;quot;).Trim();
                 }
                
                int FamcTest = FindIndexinArray(Node, &amp;quot;1 FAMC &amp;quot;);
                if (FamcTest != -1)
                {
                    I.FamC = Node[FamcTest].Replace(&amp;quot;1 FAMC &amp;quot;, &amp;quot;&amp;quot;).Replace(&amp;quot;@&amp;quot;, &amp;quot;&amp;quot;).Trim();
                }
            }
            return I;
        }
        private int FindIndexinArray(string[] Arr, string search)
        {
            int Val = -1;
            for (int i = 0; i &amp;lt; Arr.Length; i++)
            {
                if (Arr[i].Contains(search))
                {
                    Val = i;
                }
            }
            return Val;
        }
    }
}&lt;/pre&gt;</content>
    <author>
      <name>crash893.myopenid.com</name>
      <email>no-email@refactormycode.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/873-gedcom-reader" rel="alternate"/>
  </entry>
</feed>

