From: Ruby Quiz Date: 2004-11-05T23:45:36+09:00 Subject: [QUIZ] GEDCOM Parser (#6) The three rules of Ruby Quiz: 1. Please do not post any solutions or spoiler discussion for this quiz until 48 hours have passed from the time on this message. 2. Support Ruby Quiz by submitting ideas as often as you can: http://www.grayproductions.net/ruby_quiz/ 3. Enjoy! -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= by Jamis Buck GEDCOM Parser GEDCOM is the "GEnealogical Data COMmunication" file format. It is a plain-text electronic format used to transfer genealogical data. (The purpose of this quiz is not to debate whether it is a particularly *good* file format or not--but it is certainly more compact than the corresponding XML would be, and bandwidth was particularly important back when the standard was developed.) The purpose of this quiz is to develop a simple parser than can convert a GEDCOM file to XML. GEDCOM Format The GEDCOM file format is very straightforward. Each line represents a node in a tree. It looks something like this: 0 @I1@ INDI 1 NAME Jamis Gordon /Buck/ 2 SURN Buck 2 GIVN Jamis Gordon 1 SEX M ... In general, each line is formatted thus: LEVEL TAG-OR-ID [DATA] The LEVEL is an integer, representing the current depth in the tree. If subsequent lines have greater levels than the current node, they are children of the current node. TAG-OR-ID is either a tag that identifies the type of data in that node, or it is a unique identifier. Tags are 3- or 4-letter words in uppercase. The unique identifiers are always text surrounded by "@" characters (i.e., "@I54@"). If an ID is given, the DATA is the type of the subtree that is identified. So, to take the example given above apart: 1) "0 @I1@ INDI". This starts a new subtree of type INDI (individual). The id for this individual is "@I1@". 2) "1 NAME Jamis Gordon /Buck/". This starts a NAME subtree with a value of "Jamis Gordon /Buck/". 3) "2 SURN Buck". This is a subelement of the NAME subtree, of type SURN ("surname"). 4) "2 GIVN Jamis Gordon". As SURN, but specifies the given name of the individual. 5) "1 SEX M". Creates a new subelement of the INDI element, of type "SEX" (i.e., "gender"). And so forth. Variable whitespace is allowed between the level and the tag. Blank lines are ignored. The Challenge The challenge, then, is to create a parser that takes a GEDCOM file as input and converts it to XML. The snippet of GEDCOM given above would become: Buck Jamis Gordon M ... ... Sample Input There is a large GEDCOM file online containing the lineage of various European royalty. You may download it from http://search.cpan.org/src/PJCJ/Gedcom-1.11/royal.ged (yah, it's a CPAN link, but it had the highest bandwidth of any other URL I found via Google). (This particular link makes generous use of whitespace to increase the readability of the file.)