rbrainz 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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>