rbrainz 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. data/LICENSE +25 -0
  2. data/README +11 -0
  3. data/Rakefile +110 -0
  4. data/TODO +24 -0
  5. data/doc/README.rdoc +68 -0
  6. data/examples/getartist.rb +54 -0
  7. data/lib/rbrainz.rb +11 -0
  8. data/lib/rbrainz/data/countrynames.rb +259 -0
  9. data/lib/rbrainz/data/languagenames.rb +404 -0
  10. data/lib/rbrainz/data/scriptnames.rb +64 -0
  11. data/lib/rbrainz/model.rb +48 -0
  12. data/lib/rbrainz/model/alias.rb +23 -0
  13. data/lib/rbrainz/model/artist.rb +54 -0
  14. data/lib/rbrainz/model/disc.rb +30 -0
  15. data/lib/rbrainz/model/entity.rb +72 -0
  16. data/lib/rbrainz/model/incomplete_date.rb +76 -0
  17. data/lib/rbrainz/model/label.rb +55 -0
  18. data/lib/rbrainz/model/mbid.rb +82 -0
  19. data/lib/rbrainz/model/release.rb +50 -0
  20. data/lib/rbrainz/model/release_event.rb +34 -0
  21. data/lib/rbrainz/model/track.rb +27 -0
  22. data/lib/rbrainz/webservice.rb +6 -0
  23. data/lib/rbrainz/webservice/filter.rb +132 -0
  24. data/lib/rbrainz/webservice/includes.rb +150 -0
  25. data/lib/rbrainz/webservice/mbxml.rb +404 -0
  26. data/lib/rbrainz/webservice/query.rb +61 -0
  27. data/lib/rbrainz/webservice/webservice.rb +69 -0
  28. data/test/lib/test_entity.rb +58 -0
  29. data/test/lib/testing_helper.rb +13 -0
  30. data/test/test-data/README +13 -0
  31. data/test/test-data/invalid/artist/basic_1.xml +12 -0
  32. data/test/test-data/invalid/artist/basic_2.xml +12 -0
  33. data/test/test-data/invalid/artist/empty_1.xml +0 -0
  34. data/test/test-data/invalid/artist/empty_2.xml +3 -0
  35. data/test/test-data/invalid/artist/empty_3.xml +7 -0
  36. data/test/test-data/invalid/artist/search_result_1.xml +11 -0
  37. data/test/test-data/valid/artist/Tchaikovsky-1.xml +90 -0
  38. data/test/test-data/valid/artist/Tori_Amos_1.xml +8 -0
  39. data/test/test-data/valid/artist/Tori_Amos_2.xml +53 -0
  40. data/test/test-data/valid/artist/Tori_Amos_3.xml +25 -0
  41. data/test/test-data/valid/artist/Tori_Amos_4.xml +14 -0
  42. data/test/test-data/valid/artist/Tori_Amos_5.xml +13 -0
  43. data/test/test-data/valid/artist/empty_1.xml +7 -0
  44. data/test/test-data/valid/artist/empty_2.xml +11 -0
  45. data/test/test-data/valid/artist/search_result_1.xml +19 -0
  46. data/test/test-data/valid/label/Atlantic_Records_1.xml +9 -0
  47. data/test/test-data/valid/label/Atlantic_Records_2.xml +11 -0
  48. data/test/test-data/valid/label/search_result_1.xml +14 -0
  49. data/test/test-data/valid/release/Highway_61_Revisited_1.xml +68 -0
  50. data/test/test-data/valid/release/Little_Earthquakes_1.xml +24 -0
  51. data/test/test-data/valid/release/Little_Earthquakes_2.xml +73 -0
  52. data/test/test-data/valid/release/Mission_Impossible_2.xml +155 -0
  53. data/test/test-data/valid/release/Under_the_Pink_1.xml +16 -0
  54. data/test/test-data/valid/release/Under_the_Pink_2.xml +14 -0
  55. data/test/test-data/valid/release/Under_the_Pink_3.xml +16 -0
  56. data/test/test-data/valid/release/search_result_1.xml +29 -0
  57. data/test/test-data/valid/track/Silent_All_These_Years_1.xml +7 -0
  58. data/test/test-data/valid/track/Silent_All_These_Years_2.xml +21 -0
  59. data/test/test-data/valid/track/Silent_All_These_Years_3.xml +16 -0
  60. data/test/test-data/valid/track/Silent_All_These_Years_4.xml +30 -0
  61. data/test/test-data/valid/track/Silent_All_These_Years_5.xml +20 -0
  62. data/test/test-data/valid/track/search_result_1.xml +45 -0
  63. data/test/test-data/valid/user/User_1.xml +15 -0
  64. data/test/test_alias.rb +50 -0
  65. data/test/test_artist.rb +132 -0
  66. data/test/test_artist_filter.rb +36 -0
  67. data/test/test_artist_includes.rb +63 -0
  68. data/test/test_disc.rb +38 -0
  69. data/test/test_incomplete_date.rb +60 -0
  70. data/test/test_label.rb +129 -0
  71. data/test/test_label_filter.rb +36 -0
  72. data/test/test_label_includes.rb +55 -0
  73. data/test/test_mbid.rb +99 -0
  74. data/test/test_mbxml.rb +368 -0
  75. data/test/test_query.rb +24 -0
  76. data/test/test_release.rb +161 -0
  77. data/test/test_release_event.rb +67 -0
  78. data/test/test_release_filter.rb +57 -0
  79. data/test/test_release_includes.rb +73 -0
  80. data/test/test_track.rb +102 -0
  81. data/test/test_track_filter.rb +57 -0
  82. data/test/test_track_includes.rb +61 -0
  83. data/test/test_webservice.rb +23 -0
  84. metadata +138 -0
@@ -0,0 +1,61 @@
1
+ # $Id: query.rb 4 2007-05-21 02:04:26Z phw $
2
+ # Copyright (c) 2007, Philipp Wolfer
3
+ # All rights reserved.
4
+ # See LICENSE for permissions.
5
+
6
+ require 'rbrainz/webservice/webservice'
7
+ require 'rbrainz/webservice/mbxml'
8
+
9
+ module MusicBrainz
10
+ module Webservice
11
+
12
+ class Query
13
+
14
+ def initialize(webservice = nil)
15
+ @webservice = webservice.nil? ? Webservice.new : webservice
16
+ end
17
+
18
+ def get_artist_by_id(id, include = nil)
19
+ xml = @webservice.get(Model::Artist.entity_type, id, :include => include)
20
+ return MBXML.new(xml).get_entity(Model::Artist.entity_type)
21
+ end
22
+
23
+ # TODO: implement
24
+ def get_artists(filter)
25
+ raise NotImplementedError.new
26
+ end
27
+
28
+ def get_release_by_id(id, include = nil)
29
+ xml = @webservice.get(Model::Release.entity_type, id, :include => include)
30
+ return MBXML.new(xml).get_entity(Model::Release.entity_type)
31
+ end
32
+
33
+ # TODO: implement
34
+ def get_releases(filter)
35
+ raise NotImplementedError.new
36
+ end
37
+
38
+ def get_track_by_id(id, include = nil)
39
+ xml = @webservice.get(Model::Track.entity_type, id, :include => include)
40
+ return MBXML.new(xml).get_entity(Model::Track.entity_type)
41
+ end
42
+
43
+ # TODO: implement
44
+ def get_tracks(filter)
45
+ raise NotImplementedError.new
46
+ end
47
+
48
+ def get_label_by_id(id, include = nil)
49
+ xml = @webservice.get(Model::Label.entity_type, id, :include => include)
50
+ return MBXML.new(xml).get_entity(Model::Label.entity_type)
51
+ end
52
+
53
+ # TODO: implement
54
+ def get_labels(filter)
55
+ raise NotImplementedError.new
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,69 @@
1
+ # $Id: webservice.rb 4 2007-05-21 02:04:26Z phw $
2
+ # Copyright (c) 2007, Philipp Wolfer
3
+ # All rights reserved.
4
+ # See LICENSE for permissions.
5
+
6
+ require 'rbrainz/webservice/includes'
7
+ require 'rbrainz/webservice/filter'
8
+ require 'net/http'
9
+
10
+ module MusicBrainz
11
+ module Webservice
12
+
13
+ class IWebservice
14
+
15
+ # Query the Webservice with HTTP GET.
16
+ # Must be implemented by the concrete webservices.
17
+ def get(entity, id, options = {:include => nil, :filter => nil, :version => 1})
18
+ raise Exception.new('Called abstract method.')
19
+ end
20
+
21
+ # Query the Webservice with HTTP POST.
22
+ # Must be implemented by the concrete webservices.
23
+ # TODO: Specify and implement in Webservice.
24
+ def post
25
+ raise Exception.new('Called abstract method.')
26
+ end
27
+
28
+ end
29
+
30
+ # Webservice class to query the default MusicBrainz server.
31
+ # TODO: Implement authorization.
32
+ class Webservice < IWebservice
33
+
34
+ def initialize(options = {:host => nil, :port => nil, :path_prefix => nil})
35
+ @host = options[:host] ? options[:host] : 'musicbrainz.org'
36
+ @port = options[:port] ? options[:port] : 80
37
+ @path_prefix = options[:path_prefix] ? options[:path_prefix] : '/ws'
38
+ end
39
+
40
+ # Query the Webservice with HTTP GET.
41
+ # TODO: Exception handling.
42
+ def get(entity, id, options = {:include => nil, :filter => nil, :version => 1})
43
+ url = URI.parse(create_uri(entity, id, options))
44
+ req = Net::HTTP::Get.new(url.request_uri)
45
+ res = Net::HTTP.start(url.host, url.port) {|http|
46
+ http.request(req)
47
+ }
48
+ return res.body
49
+ end
50
+
51
+ private
52
+
53
+ # Builds a request URI for querying the webservice.
54
+ def create_uri(entity, id, options = {:include => nil, :filter => nil, :version => 1})
55
+ # Make sure the version is set
56
+ options[:version] = 1 if options[:version].nil?
57
+
58
+ # Build the URI
59
+ uri = 'http://%s:%d%s/%d/%s/%s?type=%s' %
60
+ [@host, @port, @path_prefix, options[:version], entity, id.uuid, 'xml']
61
+ uri += '&' + options[:include].to_s unless options[:include].nil?
62
+ uri += '&' + options[:filter].to_s unless options[:filter].nil?
63
+ return uri
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+ end
@@ -0,0 +1,58 @@
1
+ # $Id$
2
+ # Copyright (c) 2007, Philipp Wolfer
3
+ # All rights reserved.
4
+ # See LICENSE for permissions.
5
+
6
+ require 'test/unit'
7
+ require 'rbrainz/model'
8
+ include MusicBrainz
9
+
10
+ # Unit test for the entity model.
11
+ # This is only a test module which defines general
12
+ # tests on Entity. The tests should be executed by
13
+ # all subclass tests.
14
+ module TestEntity
15
+
16
+ def test_valid_mbid
17
+ entity = @tested_class.new
18
+ valid_mbid = Model::MBID.from_uuid(@tested_class.entity_type, '9d30e408-1559-448b-b491-2f8de1583ccf')
19
+
20
+ assert_equal nil, entity.id
21
+ assert_nothing_raised {entity.id = valid_mbid}
22
+ assert_equal valid_mbid, entity.id
23
+ end
24
+
25
+ def test_valid_mbid_from_uuid
26
+ entity = @tested_class.new
27
+ valid_mbid = Model::MBID.from_uuid(@tested_class.entity_type, '9d30e408-1559-448b-b491-2f8de1583ccf')
28
+
29
+ assert_equal nil, entity.id
30
+ assert_nothing_raised {entity.id = valid_mbid.uuid}
31
+ assert_equal valid_mbid, entity.id
32
+ end
33
+
34
+ def test_valid_mbid_from_uri
35
+ entity = @tested_class.new
36
+ valid_mbid = Model::MBID.from_uuid(@tested_class.entity_type, '9d30e408-1559-448b-b491-2f8de1583ccf')
37
+
38
+ assert_equal nil, entity.id
39
+ assert_nothing_raised {entity.id = valid_mbid.to_s}
40
+ assert_equal valid_mbid, entity.id
41
+ end
42
+
43
+ def test_invalid_mbid_entity_type_not_matching
44
+ entity = @tested_class.new
45
+ @invalid_entity_types.each {|type|
46
+ invalid_mbid = Model::MBID.from_uuid(type, '9d30e408-1559-448b-b491-2f8de1583ccf')
47
+ assert_raise(Model::EntityTypeNotMatchingError) {entity.id = invalid_mbid}
48
+ assert_raise(Model::EntityTypeNotMatchingError) {entity.id = invalid_mbid.to_s}
49
+ }
50
+ assert_equal nil, entity.id
51
+ end
52
+
53
+ # Relations will get implemented in version 0.1.1
54
+ #def test_relations
55
+ # assert false, 'Unit test for ' + self.class.name + ' not implemented!'
56
+ #end
57
+
58
+ end
@@ -0,0 +1,13 @@
1
+ # $Id$
2
+ # Copyright (c) 2007, Philipp Wolfer
3
+ # All rights reserved.
4
+ # See LICENSE for permissions.
5
+
6
+ # Usefull helper methods which are used in different test classes.
7
+
8
+ # Converts a query string into a hash.
9
+ def query_string_to_hash query_string
10
+ Hash[*query_string.scan(/(.+?)=(.*?)(?:&|$)/).flatten].each_value {|v|
11
+ v.gsub!(/%([0-9a-f]{2})/i) { [$1.hex].pack 'C' }
12
+ }
13
+ end
@@ -0,0 +1,13 @@
1
+ MusicBrainz Web Service XML Examples
2
+ ------------------------------------
3
+
4
+ This directory contains example XML code for testing an implementation.
5
+
6
+ Implementations MUST be able to parse the XML in the 'valid' directory.
7
+ It is perfect, schema-compliant XML.
8
+
9
+ The 'invalid' directory contains all kinds of invalid XML. Implementations
10
+ are not expected to parse those files. They MAY, however.
11
+
12
+ --
13
+ $Id: README 33 2006-01-30 09:50:19Z matt $
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <!-- invalid, not wellformed -->
4
+
5
+ <metadata xmlns="http://musicbrainz.org/ns/mmd-1.0#">
6
+
7
+ <artist-list>
8
+ <artist> <!-- tag not closed -->
9
+
10
+ </artist-list>
11
+
12
+ </metadata>
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <!-- namespace error -->
4
+
5
+ <mmd:metadata xmlns:mmd="http://musicbrainz.org/ns/mmd-1.0#">
6
+
7
+ <mmd:artist-list>
8
+ <xy:artist id="UUID"/> <!-- undeclared namespace -->
9
+
10
+ </mmd:artist-list>
11
+
12
+ </mmd:metadata>
File without changes
@@ -0,0 +1,3 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <!-- invalid, not even the root element is present -->
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <!-- invalid, namespace is missing -->
4
+
5
+ <metadata>
6
+
7
+ </metadata>
@@ -0,0 +1,11 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!-- invalid, because "score" must not be in the default namespace -->
3
+ <metadata xmlns="http://musicbrainz.org/ns/mmd-1.0#">
4
+ <artist-list>
5
+ <artist id="c0b2500e-0cef-4130-869d-732b23ed9df5" score="100">
6
+ <name>Tori Amos</name>
7
+ <sort-name>Amos, Tori</sort-name>
8
+ <life-span begin="1963-08-22"/>
9
+ </artist>
10
+ </artist-list>
11
+ </metadata>
@@ -0,0 +1,90 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <metadata xmlns="http://musicbrainz.org/ns/mmd-1.0#">
3
+ <artist id="9ddd7abc-9e1b-471d-8031-583bc6bc8be9" type="Person">
4
+ <name>Пётр Ильич Чайковский</name>
5
+ <sort-name>Tchaikovsky, Pyotr Ilyich</sort-name>
6
+ <life-span begin="1840-05-07" end="1893-11-06"/>
7
+ <alias-list>
8
+ <alias>Tchaikovsky</alias>
9
+ <alias>Peter Ilyich Tchaikovsky</alias>
10
+ <alias>Peter Tchaikovsky</alias>
11
+ <alias>Tschaikowsky</alias>
12
+ <alias>Peter Tschaikowsky</alias>
13
+ <alias>Piotr Ilyich Tchaikovsky</alias>
14
+ <alias>Piotr Tchaikovsky</alias>
15
+ <alias>Peter Iljitsch Tschaikowsky</alias>
16
+ <alias>Tchaikovsky, Peter Ilyich</alias>
17
+ <alias>Peter Ilyitch Tchaikovsky</alias>
18
+ <alias>Pjotr Ilyich Tchaikovsky</alias>
19
+ <alias>Peter I. Tschaikowsky</alias>
20
+ <alias>Pyotr Tchaikovsky</alias>
21
+ <alias>P. I. Tchaikovsky</alias>
22
+ <alias>Peter Ilich Tchaikovsky</alias>
23
+ <alias>Tchaikovsky, P.I.</alias>
24
+ <alias>Tsjaikovski</alias>
25
+ <alias>Tchaikovsky, Pyotr Ilyich</alias>
26
+ <alias>Tjajkovskij</alias>
27
+ <alias>Piotr Ilyitch Tchaikovsky</alias>
28
+ <alias>Tsjajkovskij</alias>
29
+ <alias>Peter Ilyich Tchaikovski</alias>
30
+ <alias>Peter I. Tchaikovsky</alias>
31
+ <alias>Tchaikovsky, Peter I.</alias>
32
+ <alias>Tchaikowsky</alias>
33
+ <alias>Peter Ilyich Tschaikowsky</alias>
34
+ <alias>Peter Iljitsch Tschaikowski</alias>
35
+ <alias>Pyotr Il'Yich Tchaikovsky</alias>
36
+ <alias>Tchiakovsky, Pyotr Ilich (1840-1893)</alias>
37
+ <alias>Tchaikovsky, Peter Ilyich (1840-93)</alias>
38
+ <alias>Tchaikovsky, Peter Ilyitch</alias>
39
+ <alias>Pyotr Ilyitch Tchaikovsky</alias>
40
+ <alias>Tsaikovski</alias>
41
+ <alias>Pytor Ilyich Tchaikovsky</alias>
42
+ <alias>Piotr Ilyich Tchaikowsky</alias>
43
+ <alias>Tchaikovsky - Philharmonic Orchestra</alias>
44
+ <alias>Peter Iljitsch Tschaikowsky (1840 - 1893)</alias>
45
+ <alias>Peter Tschaikovsky</alias>
46
+ <alias>Peter Ilych Tschaikowsky</alias>
47
+ <alias>Pyotr II'yich Tchaikovsky</alias>
48
+ <alias>Pytor Tchaikovsky</alias>
49
+ <alias>Pyotr Ilyich Tchaikovsky</alias>
50
+ <alias>Чайковский, Петр Ильич</alias>
51
+ <alias>Чайковский, Пётр Ильич</alias>
52
+ <alias>Петр Ильич Чайковский</alias>
53
+ <alias>Пётр Ильич Чайковский</alias>
54
+ <alias>Tchaikovsky, Peter Il'yich</alias>
55
+ <alias>Tchaikovsky, Pjotr Ilyich (1840 - 1893) </alias>
56
+ <alias>Piotr Illitch Tchaïkovsky</alias>
57
+ <alias>Piotr Ilic Ciaikovsky</alias>
58
+ <alias>Pyotr Illyich Tchaikovsky</alias>
59
+ <alias>Tchaikovsky, Piotr Ilich (1840-1893)</alias>
60
+ <alias>Peter Ilyich Tchaikovshy</alias>
61
+ <alias>Pyotr Ilyich Tchaikovsly</alias>
62
+ <alias>Peter Ilych Tchaikovsky</alias>
63
+ <alias>차이코프스키</alias>
64
+ <alias>Piotr Ilitch Tchaïkovski</alias>
65
+ <alias>Chaikovsky, P. I.</alias>
66
+ <alias>Pjotr Iljitsch Tschaikowsky</alias>
67
+ <alias>Ciaikosvsky</alias>
68
+ <alias>Tchaikovsky 1841-1893</alias>
69
+ <alias>Tchaïkovki</alias>
70
+ <alias>Piotr Ilych Chaikovsky</alias>
71
+ <alias>Pjotr Iljitsj Tsjaikovski</alias>
72
+ <alias>Pyotor Ilyich Tschaikovsky</alias>
73
+ <alias>Peter Iljitsj Tsjaikovski</alias>
74
+ <alias>P. I. Tchaikovskij</alias>
75
+ <alias>Piotr Ilich Tchaikovsky</alias>
76
+ <alias>Peter Iljitsch Tchaikovsky</alias>
77
+ <alias>Tchaikovisky</alias>
78
+ <alias>Tchaikovsy</alias>
79
+ <alias>Tchailovisky</alias>
80
+ <alias>Tchaikovskyes</alias>
81
+ <alias>Tchaikovskys</alias>
82
+ <alias>Tchaikoskvy</alias>
83
+ <alias>Piotr Il'yich Tchaikovsky</alias>
84
+ <alias>Tchaikowski</alias>
85
+ <alias>Piotr Iljič Čajkovskij</alias>
86
+ <alias>Tchaikivsky</alias>
87
+ <alias>Pyotor Tchaikovsky</alias>
88
+ </alias-list>
89
+ </artist>
90
+ </metadata>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <metadata xmlns="http://musicbrainz.org/ns/mmd-1.0#">
3
+ <artist id="c0b2500e-0cef-4130-869d-732b23ed9df5" type="Person">
4
+ <name>Tori Amos</name>
5
+ <sort-name>Amos, Tori</sort-name>
6
+ <life-span begin="1963-08-22"/>
7
+ </artist>
8
+ </metadata>
@@ -0,0 +1,53 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <metadata xmlns="http://musicbrainz.org/ns/mmd-1.0#">
3
+ <artist id="c0b2500e-0cef-4130-869d-732b23ed9df5" type="Person">
4
+ <name>Tori Amos</name>
5
+ <sort-name>Amos, Tori</sort-name>
6
+ <life-span begin="1963-08-22"/>
7
+ <release-list>
8
+ <release id="a7ccb022-f437-4492-8eee-8f85d85cdb96" type="Album Official">
9
+ <title>Strange Little Girls</title>
10
+ <asin>B00005NKYQ</asin>
11
+ <release-event-list>
12
+ <event date="2001-09-14" country="BE"/>
13
+ <event date="2001-09-14" country="FI"/>
14
+ <event date="2001-09-14" country="IE"/>
15
+ <event date="2001-09-14" country="IT"/>
16
+ <event date="2001-09-14" country="NL"/>
17
+ <event date="2001-09-17" country="AU"/>
18
+ <event date="2001-09-17" country="DE"/>
19
+ <event date="2001-09-17" country="GB"/>
20
+ <event date="2001-09-18" country="CA"/>
21
+ <event date="2001-09-18" country="SE"/>
22
+ <event date="2001-09-18" country="US"/>
23
+ <event date="2001-09-27" country="JP"/>
24
+ </release-event-list>
25
+ <disc-list count="3"/>
26
+ </release>
27
+ <release id="9cbf7040-dbdc-403c-940f-7562d9712514" type="Album Official">
28
+ <title>To Venus and Back (disc 1: Orbiting)</title>
29
+ <asin>B00001IVJS</asin>
30
+ <artist id="c0b2500e-0cef-4130-869d-732b23ed9df5"/>
31
+ <release-event-list>
32
+ <event date="1999-09-20" country="DE"/>
33
+ <event date="1999-09-20" country="GB"/>
34
+ <event date="1999-09-21" country="US"/>
35
+ </release-event-list>
36
+ <disc-list count="2"/>
37
+ </release>
38
+ <release id="290e10c5-7efc-4f60-ba2c-0dfc0208fbf5" type="Album Official">
39
+ <title>Under the Pink</title>
40
+ <asin>B000002IXU</asin>
41
+ <artist id="c0b2500e-0cef-4130-869d-732b23ed9df5"/>
42
+ <release-event-list>
43
+ <event date="1994-01-28" country="DE"/>
44
+ <event date="1994-01-31" country="GB"/>
45
+ <event date="1994-02-01" country="US"/>
46
+ <event date="1994-02-25" country="JP"/>
47
+ <event date="1994-11" country="AU"/>
48
+ </release-event-list>
49
+ <disc-list count="4"/>
50
+ </release>
51
+ </release-list>
52
+ </artist>
53
+ </metadata>
@@ -0,0 +1,25 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <metadata xmlns="http://musicbrainz.org/ns/mmd-1.0#">
3
+ <artist id="c0b2500e-0cef-4130-869d-732b23ed9df5" type="Person">
4
+ <name>Tori Amos</name>
5
+ <sort-name>Amos, Tori</sort-name>
6
+ <life-span begin="1963-08-22"/>
7
+ <relation-list target-type="Artist">
8
+ <relation type="Married"
9
+ direction="backward"
10
+ target="07538f3d-81d5-4c04-923e-4542b8ac9dbc"
11
+ begin="1998">
12
+ <artist id="07538f3d-81d5-4c04-923e-4542b8ac9dbc" type="Person">
13
+ <name>Mark Hawley</name>
14
+ <sort-name>Hawley, Mark</sort-name>
15
+ </artist>
16
+ </relation>
17
+ </relation-list>
18
+ <relation-list target-type="Url">
19
+ <relation type="Discography"
20
+ target="http://www.yessaid.com/albums.html"/>
21
+ <relation type="Wikipedia"
22
+ target="http://en.wikipedia.org/wiki/Tori_Amos"/>
23
+ </relation-list>
24
+ </artist>
25
+ </metadata>