kekka 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.rvmrc ADDED
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # This is an RVM Project .rvmrc file, used to automatically load the ruby
4
+ # development environment upon cd'ing into the directory
5
+
6
+ # First we specify our desired <ruby>[@<gemset>], the @gemset name is optional.
7
+ environment_id="ruby-1.9.2-p320"
8
+
9
+ #
10
+ # First we attempt to load the desired environment directly from the environment
11
+ # file. This is very fast and efficicent compared to running through the entire
12
+ # CLI and selector. If you want feedback on which environment was used then
13
+ # insert the word 'use' after --create as this triggers verbose mode.
14
+ #
15
+ if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
16
+ && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]] ; then
17
+ \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
18
+ else
19
+ # If the environment file has not yet been created, use the RVM CLI to select.
20
+ rvm --create use "$environment_id"
21
+ fi
22
+
23
+ #
24
+ # If you use an RVM gemset file to install a list of gems (*.gems), you can have
25
+ # it be automatically loaded. Uncomment the following and adjust the filename if
26
+ # necessary.
27
+ #
28
+ # filename=".gems"
29
+ # if [[ -s "$filename" ]] ; then
30
+ # rvm gemset import "$filename" | grep -v already | grep -v listed | grep -v complete | sed '/^$/d'
31
+ # fi
32
+
33
+ #
34
+ # If you use bundler and would like to run bundle each time you enter the
35
+ # directory, you can uncomment the following code.
36
+ #
37
+ # # Ensure that Bundler is installed. Install it if it is not.
38
+ # if ! command -v bundle >/dev/null; then
39
+ # printf "The rubygem 'bundler' is not installed. Installing it now.\n"
40
+ # gem install bundler
41
+ # fi
42
+ #
43
+ # # Bundle while reducing excess noise.
44
+ # printf "Bundling your gems. This may take a few minutes on a fresh clone.\n"
45
+ # bundle | grep -v '^Using ' | grep -v ' is complete' | sed '/^$/d'
46
+ #
47
+
data/Gemfile ADDED
@@ -0,0 +1,17 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ gem 'nokogiri', '>= 1.5'
7
+
8
+ # Add dependencies to develop your gem here.
9
+ # Include everything needed to run rake, tests, features, etc.
10
+ group :development do
11
+ gem 'rspec', '~> 2.11'
12
+ gem 'rdoc', '~> 3.12'
13
+ gem 'bundler', '~> 1.1'
14
+ gem 'jeweler', '~> 1.8'
15
+ gem 'guard-rspec', '~> 2.1'
16
+ gem 'rb-fsevent', '~> 0.9', :require => false
17
+ end
@@ -0,0 +1,54 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ coderay (1.0.8)
5
+ diff-lcs (1.1.3)
6
+ git (1.2.5)
7
+ guard (1.5.0)
8
+ listen (>= 0.4.2)
9
+ lumberjack (>= 1.0.2)
10
+ pry (>= 0.9.10)
11
+ thor (>= 0.14.6)
12
+ guard-rspec (2.1.0)
13
+ guard (>= 1.1)
14
+ rspec (~> 2.11)
15
+ jeweler (1.8.4)
16
+ bundler (~> 1.0)
17
+ git (>= 1.2.5)
18
+ rake
19
+ rdoc
20
+ json (1.7.5)
21
+ listen (0.5.3)
22
+ lumberjack (1.0.2)
23
+ method_source (0.8.1)
24
+ nokogiri (1.5.5)
25
+ pry (0.9.10)
26
+ coderay (~> 1.0.5)
27
+ method_source (~> 0.8)
28
+ slop (~> 3.3.1)
29
+ rake (0.9.2.2)
30
+ rb-fsevent (0.9.2)
31
+ rdoc (3.12)
32
+ json (~> 1.4)
33
+ rspec (2.11.0)
34
+ rspec-core (~> 2.11.0)
35
+ rspec-expectations (~> 2.11.0)
36
+ rspec-mocks (~> 2.11.0)
37
+ rspec-core (2.11.1)
38
+ rspec-expectations (2.11.3)
39
+ diff-lcs (~> 1.1.3)
40
+ rspec-mocks (2.11.3)
41
+ slop (3.3.3)
42
+ thor (0.16.0)
43
+
44
+ PLATFORMS
45
+ ruby
46
+
47
+ DEPENDENCIES
48
+ bundler (~> 1.1)
49
+ guard-rspec (~> 2.1)
50
+ jeweler (~> 1.8)
51
+ nokogiri (>= 1.5)
52
+ rb-fsevent (~> 0.9)
53
+ rdoc (~> 3.12)
54
+ rspec (~> 2.11)
@@ -0,0 +1,9 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec' do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/kekka/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
9
+
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 froderik
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,64 @@
1
+ kekka
2
+ =====
3
+
4
+ Kekka is a thin ruby library on top of the XML format [ISAF XRR](http://www.sailing.org/xml) (XML Regatta Reporting). In its first version it takes care of parsing the XML and putting data in convenient hashes - it also manages the relations between different data sets. In future versions exports will be supported also.
5
+
6
+
7
+ Usage
8
+ -----
9
+
10
+ To get hold of it:
11
+
12
+ require 'kekka'
13
+
14
+ To create a kekka:
15
+
16
+ kekka = Kekka.parse open('/path/to/xrr')
17
+
18
+ The argument to parse can be exactly the same as what [nokogiris](http://nokogiri.org/) [parse method](http://nokogiri.org/Nokogiri/XML/Document.html#method-c-parse) accepts. A kekka is actually a Hash so it is possible to use all Hash methods on it and its parts. The resulting Hash is structured exactly as the XML. On the first level there are persons, boats, teams and events. Symbols are used to get collectionesque subparts. For example - to get to boats:
19
+
20
+ kekka[:boats]
21
+
22
+ Elements that got an idea are put in a Hash with the id as key. So to get to the boat with id '9':
23
+
24
+ kekka[:boats]['9']
25
+
26
+ Attributes are downcased (by nokogiri) and used as keys in the Hash for its instance. To get the sail number for a boat:
27
+
28
+ kekka[:boats]['9']['sailnumber']
29
+
30
+ Events have a deeper structure inside. To get to races for the event with id '9':
31
+
32
+ kekka[:events]['9'][:races]
33
+
34
+ To get the race status for the race with id '32':
35
+
36
+ kekka[:events]['9'][:races]['32']['racestatus']
37
+
38
+ It is starting to get deep now and it is probably wise to split such a thing into parts.
39
+
40
+ event = kekka[:events]['9']
41
+ race = event[:races]['32']
42
+ race['racestatus']
43
+
44
+ The event also have divisions that contains both race results and series results (the latter being the sum of race results for a team). Results does not have ids so they are represented with an array. You would probably want to get all results for a race in a division and could then do seomthing like:
45
+
46
+ event = kekka[:events]['9']
47
+ division = event[:divisions]['4711']
48
+ division[:raceresults].select { |one_result| one_result['raceid'] == '32' }
49
+
50
+ Doing things like this easier may be added in future versions.
51
+
52
+
53
+ Manipulation
54
+ ------------
55
+
56
+ * Kekka adds the field 'boatclass' to the boat based on the division that the boat raced in.
57
+ * Kekka adds the field 'boatid' to race reult hashes. It finds it via 'teamid'.
58
+
59
+
60
+ Copyright
61
+ ---------
62
+
63
+ Copyright (c) 2012 Fredrik Rubensson. See LICENSE.txt for further details.
64
+
@@ -0,0 +1,46 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "kekka"
18
+ gem.homepage = "http://github.com/froderik/kekka"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Ruby ISAF XML comprehender.}
21
+ gem.description = %Q{Kekka is a parser of the XML format XRR
22
+ (XML Regatta Reporting: http://www.sailing.org/xml .) It accepts
23
+ XML on this format and sorts it in boat, event and result hashes.}
24
+ gem.email = "fredrik@eldfluga.se"
25
+ gem.authors = ["froderik"]
26
+ # dependencies defined in Gemfile
27
+ end
28
+ Jeweler::RubygemsDotOrgTasks.new
29
+
30
+ require 'rspec/core'
31
+ require 'rspec/core/rake_task'
32
+ RSpec::Core::RakeTask.new(:spec) do |spec|
33
+ spec.pattern = FileList['spec/**/*_spec.rb']
34
+ end
35
+
36
+ task :default => :spec
37
+
38
+ require 'rdoc/task'
39
+ Rake::RDocTask.new do |rdoc|
40
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
41
+
42
+ rdoc.rdoc_dir = 'rdoc'
43
+ rdoc.title = "kekka #{version}"
44
+ rdoc.rdoc_files.include('README*')
45
+ rdoc.rdoc_files.include('lib/**/*.rb')
46
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1 @@
1
+ require 'kekka/kekka'
@@ -0,0 +1,69 @@
1
+ require 'nokogiri'
2
+
3
+ class Kekka < Hash
4
+ def self.parse string_or_io
5
+ document = Nokogiri.parse string_or_io
6
+ result = Kekka.new
7
+
8
+ result[:persons] = hash_from document, 'person'
9
+ result[:boats] = hash_from document, 'boat'
10
+ result[:teams] = hash_from document, 'team' do |team_hash, node|
11
+ team_hash[:crew] = array_from node, 'crew'
12
+ end
13
+ result[:events] = hash_from document, 'event' do |event_hash, node|
14
+ event_hash[:races] = hash_from node, 'race'
15
+ event_hash[:divisions] = hash_from node, 'division' do |division_hash, node|
16
+ division_hash[:raceresults] = array_from node, 'raceresult' do |hash, node|
17
+ team = result[:teams][hash['teamid']]
18
+ hash['boatid'] = team['boatid']
19
+ end
20
+ division_hash[:seriesresults] = array_from node, 'seriesresult'
21
+ end
22
+ end
23
+
24
+ result.update_boats_with_class
25
+
26
+ result
27
+ end
28
+
29
+ def update_boats_with_class
30
+ self[:events].each do |_, event|
31
+ event[:divisions].each do |_, division|
32
+ boat_class = division['title']
33
+ division[:raceresults].each do |one_result|
34
+ team = self[:teams][one_result['teamid']]
35
+ boat = self[:boats][team['boatid']]
36
+ boat['boatclass'] = boat_class
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def self.array_from node, name
45
+ node.css(name).map do |one_node|
46
+ hash = hash_from_node one_node
47
+ yield hash, node if block_given?
48
+ hash
49
+ end
50
+ end
51
+
52
+ def self.hash_from node, name
53
+ key_value_pairs = node.css( name ).map do |matching_node|
54
+ attributes_hash = self.hash_from_node( matching_node )
55
+ yield attributes_hash, matching_node if block_given?
56
+ [matching_node["#{name}id"], attributes_hash]
57
+ end
58
+ Hash[key_value_pairs]
59
+ end
60
+
61
+ def self.hash_from_node one_node
62
+ attrs = one_node.attributes
63
+ key_value_pairs = attrs.map do |key,nokogiri_attribute|
64
+ [key, nokogiri_attribute.value]
65
+ end
66
+ Hash[key_value_pairs]
67
+ end
68
+
69
+ end
@@ -0,0 +1,113 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Kekka do
4
+ describe 'fleet racing' do
5
+ let(:kekka) { Kekka.parse( open('spec/testdata/fleet-racing-example.xml')) }
6
+
7
+ describe 'top level' do
8
+ subject { kekka }
9
+
10
+ it "should return something" do
11
+ subject.should_not be_nil
12
+ end
13
+
14
+ it "should return boats" do
15
+ subject[:boats].size.should == 9
16
+ subject[:boats].each do |_, one_boat_hash|
17
+ one_boat_hash.should have_keys(['boatname', 'sailnumber', 'boatid'])
18
+ end
19
+ end
20
+
21
+ it "should return a jolle" do
22
+ subject[:boats]['7']['boatname'].should == 'jolle'
23
+ subject[:boats]['7']['sailnumber'].should == 'FRA 739'
24
+ subject[:boats]['7']['boatclass'].should == 'Sonar'
25
+ end
26
+
27
+ it "should return events" do
28
+ subject[:events].size.should == 1
29
+ subject[:events]['9'].should have_keys(['title', 'eventid'])
30
+ end
31
+ end
32
+
33
+ describe 'one event' do
34
+ subject { kekka[:events]['9'] }
35
+
36
+ it "should return races" do
37
+ subject[:races].size.should == 10
38
+ subject[:races].each do |_, race_hash|
39
+ race_keys = ['racename', 'racenumber', 'racestartdate', 'racestarttime', 'racestatus', 'raceid']
40
+ race_hash.should have_keys(race_keys)
41
+ end
42
+ end
43
+
44
+ it "should return specifics about a race" do
45
+ subject[:races]['383']['racename' ].should == '6'
46
+ subject[:races]['383']['racenumber' ].should == '6'
47
+ subject[:races]['383']['racestartdate'].should == '20100128'
48
+ subject[:races]['383']['racestarttime'].should == '111000'
49
+ subject[:races]['383']['racestatus' ].should == 'Provisional'
50
+ end
51
+
52
+ it "should return divisions" do
53
+ subject[:divisions].size.should == 1
54
+ subject[:divisions]['1'].should have_keys ['gender', 'title']
55
+ end
56
+ end
57
+
58
+ describe 'one division' do
59
+ subject { kekka[:events]['9'][:divisions]['1'] }
60
+
61
+ it "should return specifics about a division" do
62
+ subject['title'].should == 'Sonar'
63
+ subject['gender'].should == 'Open'
64
+ end
65
+
66
+ it "should return a bunch of race results" do
67
+ subject[:raceresults].size.should == 90
68
+ subject[:raceresults].each do |one_result|
69
+ one_result.should have_keys ['teamid', 'discard', 'raceid', 'racepoints', 'scorecode', 'boatid']
70
+ end
71
+ end
72
+
73
+ it "should return a bunch of series results" do
74
+ subject[:seriesresults].size.should == 9
75
+ subject[:seriesresults].each do |one_result|
76
+ one_result.should have_keys ['teamid', 'netpoints', 'rank', 'tied', 'totalpoints']
77
+ end
78
+ end
79
+ end
80
+
81
+ describe 'teams' do
82
+ subject { kekka[:teams] }
83
+
84
+ it "should return teams" do
85
+ subject.size.should == 9
86
+ subject.each { |_, team| team.should have_keys ['gender', 'noc', 'teamid', 'teamname', 'boatid'] }
87
+ end
88
+
89
+ it "should have a crew" do
90
+ subject['GERJK6'][:crew].size.should == 3
91
+ subject['GERJK6'][:crew].each { |one_crew| one_crew.should have_keys ['personid', 'position'] }
92
+ end
93
+ end
94
+
95
+ describe 'persons' do
96
+ subject { kekka[:persons] }
97
+
98
+ it "should return persons" do
99
+ subject.size.should == 27
100
+ subject.each do |_, one_person|
101
+ one_person.should have_keys ['familyname', 'givenname', 'ifpersonid', 'noc', 'personid']
102
+ end
103
+ end
104
+
105
+ it "should return Shimon Ben Yakov" do
106
+ subject['isrsb11']['familyname'].should == 'Ben Yakov'
107
+ subject['isrsb11']['givenname'].should == 'Shimon'
108
+ subject['isrsb11']['ifpersonid'].should == 'isrsb11'
109
+ subject['isrsb11']['noc'].should == 'ISR'
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,21 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'kekka'
5
+
6
+ # Requires supporting files with custom matchers and macros, etc,
7
+ # in ./support/ and its subdirectories.
8
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+
12
+ end
13
+
14
+ RSpec::Matchers.define :have_keys do |expected_keys|
15
+ match do |hash|
16
+ expected_keys.each {|one_key| hash[one_key].should_not be_nil }
17
+ end
18
+ # failure_message_for_should do |hash|
19
+ # "expected that each of [#{expected_keys.join(',')}] should be keys to: #{hash.inspect}"
20
+ # end
21
+ end
@@ -0,0 +1,199 @@
1
+ <?xml version='1.0' encoding='UTF-8'?>
2
+ <SailingXRR Date="20100216" Time="195923" Type="SailingXRR" Version="1.3"
3
+ xsi:noNamespaceSchemaLocation="http://www.sailing.org/uploads/xml/sailingXRR_v1.3.xsd"
4
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
5
+ <Person FamilyName="Wang-Hansen" GivenName="Aleksander" IFPersonID="noraw2" NOC="NOR" PersonID="noraw2"/>
6
+ <Person FamilyName="Kristiansen" GivenName="Per Eugen" IFPersonID="norpk4" NOC="NOR" PersonID="norpk4"/>
7
+ <Person FamilyName="Solberg" GivenName="Marie" IFPersonID="norms4" NOC="NOR" PersonID="norms4"/>
8
+ <Person FamilyName="Kroker" GivenName="Jens" IFPersonID="gerjk6" NOC="GER" PersonID="gerjk6"/>
9
+ <Person FamilyName="Prem" GivenName="Robert" IFPersonID="gerrp4" NOC="GER" PersonID="gerrp4"/>
10
+ <Person FamilyName="Mainka" GivenName="Siegmund" IFPersonID="gersm16" NOC="GER" PersonID="gersm16"/>
11
+ <Person FamilyName="Ben Yakov" GivenName="Shimon" IFPersonID="isrsb11" NOC="ISR" PersonID="isrsb11"/>
12
+ <Person FamilyName="Zehavi" GivenName="Moshe" IFPersonID="isrmz1" NOC="ISR" PersonID="isrmz1"/>
13
+ <Person FamilyName="Dahan" GivenName="Schlomo" IFPersonID="isrso1" NOC="ISR" PersonID="isrso1"/>
14
+ <Person FamilyName="Murphy" GivenName="Chris" IFPersonID="usacm113" NOC="USA" PersonID="usacm113"/>
15
+ <Person FamilyName="Leatherman" GivenName="Jim" IFPersonID="usajl52" NOC="USA" PersonID="usajl52"/>
16
+ <Person FamilyName="Cogburn" GivenName="Alex" IFPersonID="usaac!" NOC="USA" PersonID="usaac!"/>
17
+ <Person FamilyName="Doerr" GivenName="Rick" IFPersonID="usaad6" NOC="USA" PersonID="usaad6"/>
18
+ <Person FamilyName="Kendell" GivenName="Brad" IFPersonID="usabk22" NOC="USA" PersonID="usabk22"/>
19
+ <Person FamilyName="Freund" GivenName="Hugh" IFPersonID="usahf12" NOC="USA" PersonID="usahf12"/>
20
+ <Person FamilyName="Twomey" GivenName="John" IFPersonID="irljt3" NOC="IRL" PersonID="irljt3"/>
21
+ <Person FamilyName="Gil" GivenName="Juan Carlos" IFPersonID="" NOC="" PersonID=""/>
22
+ <Person FamilyName="Rodriguez" GivenName="Robert" IFPersonID="usarr56" NOC="USA" PersonID="usarr56"/>
23
+ <Person FamilyName="Robertson" GivenName="John" IFPersonID="gbrjr1" NOC="GBR" PersonID="gbrjr1"/>
24
+ <Person FamilyName="Stodel" GivenName="Hannah" IFPersonID="gbrhs1" NOC="GBR" PersonID="gbrhs1"/>
25
+ <Person FamilyName="Thomas" GivenName="Steve" IFPersonID="gbrst1" NOC="GBR" PersonID="gbrst1"/>
26
+ <Person FamilyName="Jourdren" GivenName="Bruno" IFPersonID="frabj" NOC="FRA" PersonID="frabj"/>
27
+ <Person FamilyName="FLAGEUL" GivenName="ERIC" IFPersonID="fraef" NOC="FRA" PersonID="fraef"/>
28
+ <Person FamilyName="VIMONT-VICARY" GivenName="NICOLAS" IFPersonID="franv" NOC="FRA" PersonID="franv"/>
29
+ <Person FamilyName="Callahan" GivenName="Paul" IFPersonID="usapc39" NOC="USA" PersonID="usapc39"/>
30
+ <Person FamilyName="Hersey" GivenName="Mike" IFPersonID="usamh29" NOC="USA" PersonID="usamh29"/>
31
+ <Person FamilyName="Burdett" GivenName="David" IFPersonID="usadb95" NOC="USA" PersonID="usadb95"/>
32
+ <Boat BoatID="0" BoatName="" SailNumber="NOR 1"/>
33
+ <Boat BoatID="1" BoatName="" SailNumber="GER 11"/>
34
+ <Boat BoatID="2" BoatName="" SailNumber="ISR 13"/>
35
+ <Boat BoatID="3" BoatName="" SailNumber="USA 74"/>
36
+ <Boat BoatID="4" BoatName="" SailNumber="USA 674"/>
37
+ <Boat BoatID="5" BoatName="" SailNumber="IRL 694"/>
38
+ <Boat BoatID="6" BoatName="" SailNumber="GBR 702"/>
39
+ <Boat BoatID="7" BoatName="jolle" SailNumber="FRA 739"/>
40
+ <Boat BoatID="8" BoatName="" SailNumber="USA 774"/>
41
+ <Team Gender="Open" NOC="NOR" TeamID="NORAW2" TeamName="" BoatID="0">
42
+ <Crew PersonID="NORAW2" Position="S"/>
43
+ <Crew PersonID="NORPK4" Position="C"/>
44
+ <Crew PersonID="NORMS4" Position="C"/>
45
+ </Team>
46
+ <Team Gender="Open" NOC="GER" TeamID="GERJK6" TeamName="" BoatID="1">
47
+ <Crew PersonID="GERJK6" Position="S"/>
48
+ <Crew PersonID="GERRP4" Position="C"/>
49
+ <Crew PersonID="GERSM16" Position="C"/>
50
+ </Team>
51
+ <Team Gender="Open" NOC="ISR" TeamID="isrsb11" TeamName="" BoatID="2">
52
+ <Crew PersonID="isrsb11" Position="S"/>
53
+ <Crew PersonID="ISRMZ1" Position="C"/>
54
+ <Crew PersonID="ISRSO1" Position="C"/>
55
+ </Team>
56
+ <Team Gender="Open" NOC="USA" TeamID="usacm113" TeamName="" BoatID="3">
57
+ <Crew PersonID="usacm113" Position="S"/>
58
+ <Crew PersonID="USAJL52" Position="C"/>
59
+ <Crew PersonID="USAAC!" Position="C"/>
60
+ </Team>
61
+ <Team Gender="Open" NOC="USA" TeamID="USAAD6" TeamName="" BoatID="4">
62
+ <Crew PersonID="USAAD6" Position="S"/>
63
+ <Crew PersonID="USABK22" Position="C"/>
64
+ <Crew PersonID="USAHF12" Position="C"/>
65
+ </Team>
66
+ <Team Gender="Open" NOC="IRL" TeamID="IRLJT3" TeamName="" BoatID="5">
67
+ <Crew PersonID="IRLJT3" Position="S"/>
68
+ <Crew PersonID="" Position="C"/>
69
+ <Crew PersonID="USARR56" Position="C"/>
70
+ </Team>
71
+ <Team Gender="Open" NOC="GBR" TeamID="GBRJR1" TeamName="" BoatID="6">
72
+ <Crew PersonID="GBRJR1" Position="S"/>
73
+ <Crew PersonID="GBRHS1" Position="C"/>
74
+ <Crew PersonID="GBRST1" Position="C"/>
75
+ </Team>
76
+ <Team Gender="Open" NOC="FRA" TeamID="FRABJ" TeamName="" BoatID="7">
77
+ <Crew PersonID="FRABJ" Position="S"/>
78
+ <Crew PersonID="FRAEF" Position="C"/>
79
+ <Crew PersonID="FRANV" Position="C"/>
80
+ </Team>
81
+ <Team Gender="Open" NOC="USA" TeamID="USAPC39" TeamName="" BoatID="8">
82
+ <Crew PersonID="USAPC39" Position="S"/>
83
+ <Crew PersonID="usamh29" Position="C"/>
84
+ <Crew PersonID="usadb95" Position="C"/>
85
+ </Team>
86
+ <Event EventID="9" IFEventID="9756" Title="Sonar">
87
+ <Race RaceID="30" RaceName="1" RaceNumber="1" RaceStartDate="20100126" RaceStartTime="110000" RaceStatus="Provisional"/>
88
+ <Race RaceID="32" RaceName="2" RaceNumber="2" RaceStartDate="20100126" RaceStartTime="122100" RaceStatus="Provisional"/>
89
+ <Race RaceID="33" RaceName="3" RaceNumber="3" RaceStartDate="20100126" RaceStartTime="140515" RaceStatus="Provisional"/>
90
+ <Race RaceID="111" RaceName="4" RaceNumber="4" RaceStartDate="20100127" RaceStartTime="123000" RaceStatus="Provisional"/>
91
+ <Race RaceID="112" RaceName="5" RaceNumber="5" RaceStartDate="20100127" RaceStartTime="140000" RaceStatus="Provisional"/>
92
+ <Race RaceID="383" RaceName="6" RaceNumber="6" RaceStartDate="20100128" RaceStartTime="111000" RaceStatus="Provisional"/>
93
+ <Race RaceID="395" RaceName="7" RaceNumber="7" RaceStartDate="20100128" RaceStartTime="122505" RaceStatus="Provisional"/>
94
+ <Race RaceID="413" RaceName="8" RaceNumber="8" RaceStartDate="20100128" RaceStartTime="144505" RaceStatus="Provisional"/>
95
+ <Race RaceID="415" RaceName="9" RaceNumber="9" RaceStartDate="20100129" RaceStartTime="113005" RaceStatus="Provisional"/>
96
+ <Race RaceID="416" RaceName="10" RaceNumber="10" RaceStartDate="20100129" RaceStartTime="130000" RaceStatus="Provisional"/>
97
+ <Division DivisionID="1" Gender="Open" IFDivisionID="15983" Title="Sonar">
98
+ <RaceResult TeamID="FRABJ" Discard="false" RaceID="111" RacePoints="2" ScoreCode=""/>
99
+ <RaceResult TeamID="FRABJ" Discard="false" RaceID="112" RacePoints="2" ScoreCode=""/>
100
+ <RaceResult TeamID="FRABJ" Discard="false" RaceID="30" RacePoints="7" ScoreCode=""/>
101
+ <RaceResult TeamID="FRABJ" Discard="false" RaceID="32" RacePoints="1" ScoreCode=""/>
102
+ <RaceResult TeamID="FRABJ" Discard="false" RaceID="33" RacePoints="3" ScoreCode=""/>
103
+ <RaceResult TeamID="FRABJ" Discard="false" RaceID="383" RacePoints="5" ScoreCode=""/>
104
+ <RaceResult TeamID="FRABJ" Discard="false" RaceID="395" RacePoints="6" ScoreCode=""/>
105
+ <RaceResult TeamID="FRABJ" Discard="false" RaceID="413" RacePoints="4" ScoreCode=""/>
106
+ <RaceResult TeamID="FRABJ" Discard="false" RaceID="415" RacePoints="1" ScoreCode=""/>
107
+ <RaceResult TeamID="FRABJ" Discard="true" RaceID="416" RacePoints="10" ScoreCode="RAF"/>
108
+ <RaceResult TeamID="GBRJR1" Discard="false" RaceID="111" RacePoints="6" ScoreCode=""/>
109
+ <RaceResult TeamID="GBRJR1" Discard="false" RaceID="112" RacePoints="1" ScoreCode=""/>
110
+ <RaceResult TeamID="GBRJR1" Discard="false" RaceID="30" RacePoints="3" ScoreCode=""/>
111
+ <RaceResult TeamID="GBRJR1" Discard="false" RaceID="32" RacePoints="3" ScoreCode=""/>
112
+ <RaceResult TeamID="GBRJR1" Discard="false" RaceID="33" RacePoints="2" ScoreCode=""/>
113
+ <RaceResult TeamID="GBRJR1" Discard="false" RaceID="383" RacePoints="2" ScoreCode=""/>
114
+ <RaceResult TeamID="GBRJR1" Discard="false" RaceID="395" RacePoints="2" ScoreCode=""/>
115
+ <RaceResult TeamID="GBRJR1" Discard="false" RaceID="413" RacePoints="1" ScoreCode=""/>
116
+ <RaceResult TeamID="GBRJR1" Discard="false" RaceID="416" RacePoints="4" ScoreCode=""/>
117
+ <RaceResult TeamID="GBRJR1" Discard="true" RaceID="415" RacePoints="8" ScoreCode=""/>
118
+ <RaceResult TeamID="GERJK6" Discard="false" RaceID="111" RacePoints="3" ScoreCode=""/>
119
+ <RaceResult TeamID="GERJK6" Discard="false" RaceID="30" RacePoints="2" ScoreCode=""/>
120
+ <RaceResult TeamID="GERJK6" Discard="false" RaceID="32" RacePoints="2" ScoreCode=""/>
121
+ <RaceResult TeamID="GERJK6" Discard="false" RaceID="33" RacePoints="5" ScoreCode=""/>
122
+ <RaceResult TeamID="GERJK6" Discard="false" RaceID="383" RacePoints="7" ScoreCode=""/>
123
+ <RaceResult TeamID="GERJK6" Discard="false" RaceID="395" RacePoints="7" ScoreCode=""/>
124
+ <RaceResult TeamID="GERJK6" Discard="false" RaceID="413" RacePoints="6" ScoreCode=""/>
125
+ <RaceResult TeamID="GERJK6" Discard="false" RaceID="415" RacePoints="3" ScoreCode=""/>
126
+ <RaceResult TeamID="GERJK6" Discard="false" RaceID="416" RacePoints="3" ScoreCode=""/>
127
+ <RaceResult TeamID="GERJK6" Discard="true" RaceID="112" RacePoints="7" ScoreCode=""/>
128
+ <RaceResult TeamID="IRLJT3" Discard="false" RaceID="111" RacePoints="5" ScoreCode=""/>
129
+ <RaceResult TeamID="IRLJT3" Discard="false" RaceID="112" RacePoints="8" ScoreCode=""/>
130
+ <RaceResult TeamID="IRLJT3" Discard="false" RaceID="32" RacePoints="7" ScoreCode=""/>
131
+ <RaceResult TeamID="IRLJT3" Discard="false" RaceID="33" RacePoints="7" ScoreCode=""/>
132
+ <RaceResult TeamID="IRLJT3" Discard="false" RaceID="383" RacePoints="8" ScoreCode=""/>
133
+ <RaceResult TeamID="IRLJT3" Discard="false" RaceID="395" RacePoints="9" ScoreCode=""/>
134
+ <RaceResult TeamID="IRLJT3" Discard="false" RaceID="413" RacePoints="5" ScoreCode=""/>
135
+ <RaceResult TeamID="IRLJT3" Discard="false" RaceID="415" RacePoints="9" ScoreCode=""/>
136
+ <RaceResult TeamID="IRLJT3" Discard="false" RaceID="416" RacePoints="7" ScoreCode=""/>
137
+ <RaceResult TeamID="IRLJT3" Discard="true" RaceID="30" RacePoints="9" ScoreCode=""/>
138
+ <RaceResult TeamID="isrsb11" Discard="false" RaceID="112" RacePoints="5" ScoreCode=""/>
139
+ <RaceResult TeamID="isrsb11" Discard="false" RaceID="30" RacePoints="5" ScoreCode=""/>
140
+ <RaceResult TeamID="isrsb11" Discard="false" RaceID="32" RacePoints="5" ScoreCode=""/>
141
+ <RaceResult TeamID="isrsb11" Discard="false" RaceID="33" RacePoints="6" ScoreCode=""/>
142
+ <RaceResult TeamID="isrsb11" Discard="false" RaceID="383" RacePoints="6" ScoreCode=""/>
143
+ <RaceResult TeamID="isrsb11" Discard="false" RaceID="395" RacePoints="5" ScoreCode=""/>
144
+ <RaceResult TeamID="isrsb11" Discard="false" RaceID="413" RacePoints="8" ScoreCode=""/>
145
+ <RaceResult TeamID="isrsb11" Discard="false" RaceID="415" RacePoints="6" ScoreCode=""/>
146
+ <RaceResult TeamID="isrsb11" Discard="false" RaceID="416" RacePoints="6" ScoreCode=""/>
147
+ <RaceResult TeamID="isrsb11" Discard="true" RaceID="111" RacePoints="8" ScoreCode=""/>
148
+ <RaceResult TeamID="NORAW2" Discard="false" RaceID="111" RacePoints="1" ScoreCode=""/>
149
+ <RaceResult TeamID="NORAW2" Discard="false" RaceID="112" RacePoints="3" ScoreCode=""/>
150
+ <RaceResult TeamID="NORAW2" Discard="false" RaceID="30" RacePoints="1" ScoreCode=""/>
151
+ <RaceResult TeamID="NORAW2" Discard="false" RaceID="32" RacePoints="4" ScoreCode=""/>
152
+ <RaceResult TeamID="NORAW2" Discard="false" RaceID="33" RacePoints="1" ScoreCode=""/>
153
+ <RaceResult TeamID="NORAW2" Discard="false" RaceID="383" RacePoints="1" ScoreCode=""/>
154
+ <RaceResult TeamID="NORAW2" Discard="false" RaceID="395" RacePoints="1" ScoreCode=""/>
155
+ <RaceResult TeamID="NORAW2" Discard="false" RaceID="413" RacePoints="3" ScoreCode=""/>
156
+ <RaceResult TeamID="NORAW2" Discard="false" RaceID="416" RacePoints="1" ScoreCode=""/>
157
+ <RaceResult TeamID="NORAW2" Discard="true" RaceID="415" RacePoints="7" ScoreCode=""/>
158
+ <RaceResult TeamID="USAAD6" Discard="false" RaceID="111" RacePoints="4" ScoreCode=""/>
159
+ <RaceResult TeamID="USAAD6" Discard="false" RaceID="112" RacePoints="4" ScoreCode=""/>
160
+ <RaceResult TeamID="USAAD6" Discard="false" RaceID="30" RacePoints="4" ScoreCode=""/>
161
+ <RaceResult TeamID="USAAD6" Discard="false" RaceID="33" RacePoints="4" ScoreCode=""/>
162
+ <RaceResult TeamID="USAAD6" Discard="false" RaceID="383" RacePoints="3" ScoreCode=""/>
163
+ <RaceResult TeamID="USAAD6" Discard="false" RaceID="395" RacePoints="3" ScoreCode=""/>
164
+ <RaceResult TeamID="USAAD6" Discard="false" RaceID="413" RacePoints="2" ScoreCode=""/>
165
+ <RaceResult TeamID="USAAD6" Discard="false" RaceID="415" RacePoints="2" ScoreCode=""/>
166
+ <RaceResult TeamID="USAAD6" Discard="false" RaceID="416" RacePoints="2" ScoreCode=""/>
167
+ <RaceResult TeamID="USAAD6" Discard="true" RaceID="32" RacePoints="8" ScoreCode=""/>
168
+ <RaceResult TeamID="usacm113" Discard="false" RaceID="111" RacePoints="9" ScoreCode=""/>
169
+ <RaceResult TeamID="usacm113" Discard="false" RaceID="112" RacePoints="9" ScoreCode=""/>
170
+ <RaceResult TeamID="usacm113" Discard="false" RaceID="30" RacePoints="8" ScoreCode=""/>
171
+ <RaceResult TeamID="usacm113" Discard="false" RaceID="33" RacePoints="8" ScoreCode=""/>
172
+ <RaceResult TeamID="usacm113" Discard="false" RaceID="383" RacePoints="9" ScoreCode=""/>
173
+ <RaceResult TeamID="usacm113" Discard="false" RaceID="395" RacePoints="8" ScoreCode=""/>
174
+ <RaceResult TeamID="usacm113" Discard="false" RaceID="413" RacePoints="7" ScoreCode=""/>
175
+ <RaceResult TeamID="usacm113" Discard="false" RaceID="415" RacePoints="5" ScoreCode=""/>
176
+ <RaceResult TeamID="usacm113" Discard="false" RaceID="416" RacePoints="5" ScoreCode=""/>
177
+ <RaceResult TeamID="usacm113" Discard="true" RaceID="32" RacePoints="9" ScoreCode=""/>
178
+ <RaceResult TeamID="USAPC39" Discard="false" RaceID="111" RacePoints="7" ScoreCode=""/>
179
+ <RaceResult TeamID="USAPC39" Discard="false" RaceID="112" RacePoints="6" ScoreCode=""/>
180
+ <RaceResult TeamID="USAPC39" Discard="false" RaceID="30" RacePoints="6" ScoreCode=""/>
181
+ <RaceResult TeamID="USAPC39" Discard="false" RaceID="32" RacePoints="6" ScoreCode=""/>
182
+ <RaceResult TeamID="USAPC39" Discard="false" RaceID="383" RacePoints="4" ScoreCode=""/>
183
+ <RaceResult TeamID="USAPC39" Discard="false" RaceID="395" RacePoints="4" ScoreCode=""/>
184
+ <RaceResult TeamID="USAPC39" Discard="false" RaceID="413" RacePoints="9" ScoreCode=""/>
185
+ <RaceResult TeamID="USAPC39" Discard="false" RaceID="415" RacePoints="4" ScoreCode=""/>
186
+ <RaceResult TeamID="USAPC39" Discard="false" RaceID="416" RacePoints="10" ScoreCode="DNS"/>
187
+ <RaceResult TeamID="USAPC39" Discard="true" RaceID="33" RacePoints="10" ScoreCode="DNF"/>
188
+ <SeriesResult TeamID="NORAW2" NetPoints="16" Rank="1" Tied="false" TotalPoints="46"/>
189
+ <SeriesResult TeamID="GERJK6" NetPoints="38" Rank="5" Tied="false" TotalPoints="90"/>
190
+ <SeriesResult TeamID="isrsb11" NetPoints="52" Rank="6" Tied="false" TotalPoints="120"/>
191
+ <SeriesResult TeamID="usacm113" NetPoints="68" Rank="9" Tied="false" TotalPoints="154"/>
192
+ <SeriesResult TeamID="USAAD6" NetPoints="28" Rank="3" Tied="false" TotalPoints="72"/>
193
+ <SeriesResult TeamID="IRLJT3" NetPoints="65" Rank="8" Tied="false" TotalPoints="148"/>
194
+ <SeriesResult TeamID="GBRJR1" NetPoints="24" Rank="2" Tied="false" TotalPoints="64"/>
195
+ <SeriesResult TeamID="FRABJ" NetPoints="31" Rank="4" Tied="false" TotalPoints="82"/>
196
+ <SeriesResult TeamID="USAPC39" NetPoints="56" Rank="7" Tied="false" TotalPoints="132"/>
197
+ </Division>
198
+ </Event>
199
+ </SailingXRR>
metadata ADDED
@@ -0,0 +1,179 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kekka
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - froderik
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-26 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: nokogiri
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '1.5'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '1.5'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '2.11'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '2.11'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rdoc
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '3.12'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '3.12'
62
+ - !ruby/object:Gem::Dependency
63
+ name: bundler
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '1.1'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '1.1'
78
+ - !ruby/object:Gem::Dependency
79
+ name: jeweler
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: '1.8'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: '1.8'
94
+ - !ruby/object:Gem::Dependency
95
+ name: guard-rspec
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: '2.1'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: '2.1'
110
+ - !ruby/object:Gem::Dependency
111
+ name: rb-fsevent
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: '0.9'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: '0.9'
126
+ description: ! "Kekka is a parser of the XML format XRR\n (XML Regatta Reporting:
127
+ http://www.sailing.org/xml .) It accepts\n XML on this format and sorts it in
128
+ boat, event and result hashes."
129
+ email: fredrik@eldfluga.se
130
+ executables: []
131
+ extensions: []
132
+ extra_rdoc_files:
133
+ - LICENSE.txt
134
+ - README.md
135
+ files:
136
+ - .document
137
+ - .rspec
138
+ - .rvmrc
139
+ - Gemfile
140
+ - Gemfile.lock
141
+ - Guardfile
142
+ - LICENSE.txt
143
+ - README.md
144
+ - Rakefile
145
+ - VERSION
146
+ - lib/kekka.rb
147
+ - lib/kekka/kekka.rb
148
+ - spec/kekka_spec.rb
149
+ - spec/spec_helper.rb
150
+ - spec/testdata/fleet-racing-example.xml
151
+ homepage: http://github.com/froderik/kekka
152
+ licenses:
153
+ - MIT
154
+ post_install_message:
155
+ rdoc_options: []
156
+ require_paths:
157
+ - lib
158
+ required_ruby_version: !ruby/object:Gem::Requirement
159
+ none: false
160
+ requirements:
161
+ - - ! '>='
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ segments:
165
+ - 0
166
+ hash: 651034944445132888
167
+ required_rubygems_version: !ruby/object:Gem::Requirement
168
+ none: false
169
+ requirements:
170
+ - - ! '>='
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ requirements: []
174
+ rubyforge_project:
175
+ rubygems_version: 1.8.24
176
+ signing_key:
177
+ specification_version: 3
178
+ summary: Ruby ISAF XML comprehender.
179
+ test_files: []