datacite-mapping 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +42 -0
  3. data/.rubocop.yml +28 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +2 -0
  6. data/.yardopts +2 -0
  7. data/CHANGES.md +3 -0
  8. data/Gemfile +3 -0
  9. data/LICENSE.md +22 -0
  10. data/README.md +168 -0
  11. data/Rakefile +49 -0
  12. data/datacite-mapping.gemspec +37 -0
  13. data/examples/reading.rb +75 -0
  14. data/examples/writing.rb +49 -0
  15. data/lib/datacite/mapping.rb +36 -0
  16. data/lib/datacite/mapping/alternate_identifier.rb +45 -0
  17. data/lib/datacite/mapping/contributor.rb +125 -0
  18. data/lib/datacite/mapping/creator.rb +48 -0
  19. data/lib/datacite/mapping/date.rb +153 -0
  20. data/lib/datacite/mapping/description.rb +121 -0
  21. data/lib/datacite/mapping/geo_location.rb +49 -0
  22. data/lib/datacite/mapping/geo_location_box.rb +137 -0
  23. data/lib/datacite/mapping/geo_location_point.rb +102 -0
  24. data/lib/datacite/mapping/identifier.rb +45 -0
  25. data/lib/datacite/mapping/module_info.rb +12 -0
  26. data/lib/datacite/mapping/name_identifier.rb +48 -0
  27. data/lib/datacite/mapping/related_identifier.rb +209 -0
  28. data/lib/datacite/mapping/resource.rb +201 -0
  29. data/lib/datacite/mapping/resource_type.rb +83 -0
  30. data/lib/datacite/mapping/rights.rb +36 -0
  31. data/lib/datacite/mapping/subject.rb +55 -0
  32. data/lib/datacite/mapping/title.rb +69 -0
  33. data/spec/.rubocop.yml +7 -0
  34. data/spec/data/resource.xml +61 -0
  35. data/spec/rspec_custom_matchers.rb +69 -0
  36. data/spec/spec_helper.rb +31 -0
  37. data/spec/unit/datacite/mapping/alternate_identifier_spec.rb +60 -0
  38. data/spec/unit/datacite/mapping/contributor_spec.rb +129 -0
  39. data/spec/unit/datacite/mapping/creator_spec.rb +125 -0
  40. data/spec/unit/datacite/mapping/date_spec.rb +246 -0
  41. data/spec/unit/datacite/mapping/description_spec.rb +89 -0
  42. data/spec/unit/datacite/mapping/geo_location_box_spec.rb +241 -0
  43. data/spec/unit/datacite/mapping/geo_location_point_spec.rb +148 -0
  44. data/spec/unit/datacite/mapping/geo_location_spec.rb +116 -0
  45. data/spec/unit/datacite/mapping/identifier_spec.rb +75 -0
  46. data/spec/unit/datacite/mapping/name_identifier_spec.rb +89 -0
  47. data/spec/unit/datacite/mapping/related_identifier_spec.rb +157 -0
  48. data/spec/unit/datacite/mapping/resource_spec.rb +727 -0
  49. data/spec/unit/datacite/mapping/resource_type_spec.rb +69 -0
  50. data/spec/unit/datacite/mapping/rights_spec.rb +78 -0
  51. data/spec/unit/datacite/mapping/subject_spec.rb +108 -0
  52. data/spec/unit/datacite/mapping/title_spec.rb +113 -0
  53. metadata +262 -0
@@ -0,0 +1,12 @@
1
+ module Datacite
2
+ module Mapping
3
+ # The name of this gem
4
+ NAME = 'datacite-mapping'
5
+
6
+ # The version of this gem
7
+ VERSION = '0.1.0'
8
+
9
+ # The copyright notice for this gem
10
+ COPYRIGHT = 'Copyright (c) 2015 The Regents of the University of California'
11
+ end
12
+ end
@@ -0,0 +1,48 @@
1
+ require 'xml/mapping_extensions'
2
+
3
+ module Datacite
4
+ module Mapping
5
+ # Uniquely identifies an individual or legal entity, according to various schemes.
6
+ class NameIdentifier
7
+ include XML::Mapping
8
+
9
+ root_element_name 'nameIdentifier'
10
+
11
+ # @!attribute [rw] scheme
12
+ # @return [String] the name identifier scheme. Cannot be nil.
13
+ text_node :scheme, '@nameIdentifierScheme'
14
+ # @!attribute [rw] scheme_uri
15
+ # @return [URI, nil] the URI of the identifier scheme. Optional.
16
+ uri_node :scheme_uri, '@schemeURI', default_value: nil
17
+ # @!attribute [rw] value
18
+ # @return [String] the identifier value. Cannot be nil.
19
+ text_node :value, 'text()'
20
+
21
+ alias_method :_scheme=, :scheme=
22
+ private :_scheme=
23
+
24
+ alias_method :_value=, :value=
25
+ private :_value=
26
+
27
+ # Initializes a new {NameIdentifier}
28
+ # @param scheme [Scheme] the name identifier scheme. Cannot be nil.
29
+ # @param scheme_uri [URI, nil] the URI of the identifier scheme. Optional.
30
+ # @param value [String] the identifier value. Cannot be nil.
31
+ def initialize(scheme:, scheme_uri: nil, value:)
32
+ self.scheme = scheme
33
+ self.scheme_uri = scheme_uri
34
+ self.value = value
35
+ end
36
+
37
+ def scheme=(v)
38
+ fail ArgumentError, 'Scheme cannot be empty or nil' unless v && !v.empty?
39
+ self._scheme = v
40
+ end
41
+
42
+ def value=(v)
43
+ fail ArgumentError, 'Value cannot be empty or nil' unless v && !v.empty?
44
+ self._value = v
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,209 @@
1
+ require 'xml/mapping_extensions'
2
+
3
+ module Datacite
4
+ module Mapping
5
+
6
+ # Controlled list of relationships of the {Resource} to a related resource.
7
+ class RelationType < TypesafeEnum::Base
8
+ # @!parse IS_CITED_BY = IsCitedBy
9
+ new :IS_CITED_BY, 'IsCitedBy'
10
+
11
+ # @!parse CITES = Cites
12
+ new :CITES, 'Cites'
13
+
14
+ # @!parse IS_SUPPLEMENT_TO = IsSupplementTo
15
+ new :IS_SUPPLEMENT_TO, 'IsSupplementTo'
16
+
17
+ # @!parse IS_SUPPLEMENTED_BY = IsSupplementedBy
18
+ new :IS_SUPPLEMENTED_BY, 'IsSupplementedBy'
19
+
20
+ # @!parse IS_CONTINUED_BY = IsContinuedBy
21
+ new :IS_CONTINUED_BY, 'IsContinuedBy'
22
+
23
+ # @!parse CONTINUES = Continues
24
+ new :CONTINUES, 'Continues'
25
+
26
+ # @!parse HAS_METADATA = HasMetadata
27
+ new :HAS_METADATA, 'HasMetadata'
28
+
29
+ # @!parse IS_METADATA_FOR = IsMetadataFor
30
+ new :IS_METADATA_FOR, 'IsMetadataFor'
31
+
32
+ # @!parse IS_NEW_VERSION_OF = IsNewVersionOf
33
+ new :IS_NEW_VERSION_OF, 'IsNewVersionOf'
34
+
35
+ # @!parse IS_PREVIOUS_VERSION_OF = IsPreviousVersionOf
36
+ new :IS_PREVIOUS_VERSION_OF, 'IsPreviousVersionOf'
37
+
38
+ # @!parse IS_PART_OF = IsPartOf
39
+ new :IS_PART_OF, 'IsPartOf'
40
+
41
+ # @!parse HAS_PART = HasPart
42
+ new :HAS_PART, 'HasPart'
43
+
44
+ # @!parse IS_REFERENCED_BY = IsReferencedBy
45
+ new :IS_REFERENCED_BY, 'IsReferencedBy'
46
+
47
+ # @!parse REFERENCES = References
48
+ new :REFERENCES, 'References'
49
+
50
+ # @!parse IS_DOCUMENTED_BY = IsDocumentedBy
51
+ new :IS_DOCUMENTED_BY, 'IsDocumentedBy'
52
+
53
+ # @!parse DOCUMENTS = Documents
54
+ new :DOCUMENTS, 'Documents'
55
+
56
+ # @!parse IS_COMPILED_BY = IsCompiledBy
57
+ new :IS_COMPILED_BY, 'IsCompiledBy'
58
+
59
+ # @!parse COMPILES = Compiles
60
+ new :COMPILES, 'Compiles'
61
+
62
+ # @!parse IS_VARIANT_FORM_OF = IsVariantFormOf
63
+ new :IS_VARIANT_FORM_OF, 'IsVariantFormOf'
64
+
65
+ # @!parse IS_ORIGINAL_FORM_OF = IsOriginalFormOf
66
+ new :IS_ORIGINAL_FORM_OF, 'IsOriginalFormOf'
67
+
68
+ # @!parse IS_IDENTICAL_TO = IsIdenticalTo
69
+ new :IS_IDENTICAL_TO, 'IsIdenticalTo'
70
+
71
+ # @!parse IS_REVIEWED_BY = IsReviewedBy
72
+ new :IS_REVIEWED_BY, 'IsReviewedBy'
73
+
74
+ # @!parse REVIEWS = Reviews
75
+ new :REVIEWS, 'Reviews'
76
+
77
+ # @!parse IS_DERIVED_FROM = IsDerivedFrom
78
+ new :IS_DERIVED_FROM, 'IsDerivedFrom'
79
+
80
+ # @!parse IS_SOURCE_OF = IsSourceOf
81
+ new :IS_SOURCE_OF, 'IsSourceOf'
82
+
83
+ end
84
+
85
+ # Controlled list of related identifier types.
86
+ class RelatedIdentifierType < TypesafeEnum::Base
87
+ # @!parse ARK = ARK
88
+ new :ARK, 'ARK'
89
+
90
+ # @!parse ARXIV = arXiv
91
+ new :ARXIV, 'arXiv'
92
+
93
+ # @!parse BIBCODE = bibcode
94
+ new :BIBCODE, 'bibcode'
95
+
96
+ # @!parse DOI = DOI
97
+ new :DOI, 'DOI'
98
+
99
+ # @!parse EAN13 = EAN13
100
+ new :EAN13, 'EAN13'
101
+
102
+ # @!parse EISSN = EISSN
103
+ new :EISSN, 'EISSN'
104
+
105
+ # @!parse HANDLE = Handle
106
+ new :HANDLE, 'Handle'
107
+
108
+ # @!parse ISBN = ISBN
109
+ new :ISBN, 'ISBN'
110
+
111
+ # @!parse ISSN = ISSN
112
+ new :ISSN, 'ISSN'
113
+
114
+ # @!parse ISTC = ISTC
115
+ new :ISTC, 'ISTC'
116
+
117
+ # @!parse LISSN = LISSN
118
+ new :LISSN, 'LISSN'
119
+
120
+ # @!parse LSID = LSID
121
+ new :LSID, 'LSID'
122
+
123
+ # @!parse PMID = PMID
124
+ new :PMID, 'PMID'
125
+
126
+ # @!parse PURL = PURL
127
+ new :PURL, 'PURL'
128
+
129
+ # @!parse UPC = UPC
130
+ new :UPC, 'UPC'
131
+
132
+ # @!parse URL = URL
133
+ new :URL, 'URL'
134
+
135
+ # @!parse URN = URN
136
+ new :URN, 'URN'
137
+
138
+ end
139
+
140
+ # Globally unique identifier of a related resource.
141
+ class RelatedIdentifier
142
+ include XML::Mapping
143
+
144
+ root_element_name 'relatedIdentifier'
145
+
146
+ # @!attribute [rw] relation_type
147
+ # @return [RelationType] the relationship of the {Resource} to the related resource. Cannot be nil.
148
+ typesafe_enum_node :relation_type, '@relationType', class: RelationType
149
+
150
+ # @!attribute [rw] value
151
+ # @return [String] the identifier value. Cannot be nil.
152
+ text_node :value, 'text()'
153
+
154
+ # @!attribute [rw] identifier_type
155
+ # @return [RelatedIdentifierType] the type of the related identifier. Cannot be nil.
156
+ typesafe_enum_node :identifier_type, '@relatedIdentifierType', class: RelatedIdentifierType
157
+
158
+ # @!attribute [rw] related_metadata_scheme
159
+ # @return [String, nil] the name of the metadata scheme. Used only with `HasMetadata`/`IsMetadataFor`. Optional.
160
+ text_node :related_metadata_scheme, '@relatedMetadataScheme', default_value: nil
161
+
162
+ # @!attribute [rw] scheme_uri
163
+ # @return [URI, nil] the URI of the metadata scheme. Used only with `HasMetadata`/`IsMetadataFor`. Optional.
164
+ uri_node :scheme_uri, '@schemeURI', default_value: nil
165
+
166
+ # @!attribute [rw] scheme_type
167
+ # @return [String, nil] the type of the metadata scheme. Used only with `HasMetadata`/`IsMetadataFor`. Optional.
168
+ text_node :scheme_type, '@schemeType', default_value: nil
169
+
170
+ alias_method :_relation_type=, :relation_type=
171
+ private :_relation_type=
172
+ alias_method :_value=, :value=
173
+ private :_value=
174
+ alias_method :_identifier_type=, :identifier_type=
175
+ private :_identifier_type=
176
+
177
+ # Initializes a new {RelatedIdentifier}.
178
+ # @param relation_type [RelationType] the relationship of the {Resource} to the related resource. Cannot be nil.
179
+ # @param value [String] the identifier value. Cannot be nil.
180
+ # @param identifier_type [RelatedIdentifierType] the type of the related identifier. Cannot be nil.
181
+ # @param related_metadata_scheme [String, nil] the name of the metadata scheme. Used only with `HasMetadata`/`IsMetadataFor`. Optional.
182
+ # @param scheme_uri [URI, nil] the URI of the metadata scheme. Used only with `HasMetadata`/`IsMetadataFor`. Optional.
183
+ # @param scheme_type [String, nil] the type of the metadata scheme. Used only with `HasMetadata`/`IsMetadataFor`. Optional.
184
+ def initialize(relation_type:, value:, identifier_type:, related_metadata_scheme: nil, scheme_uri: nil, scheme_type: nil) # rubocop:disable Metrics/ParameterLists
185
+ self.relation_type = relation_type
186
+ self.value = value
187
+ self.identifier_type = identifier_type
188
+ self.related_metadata_scheme = related_metadata_scheme
189
+ self.scheme_uri = scheme_uri
190
+ self.scheme_type = scheme_type
191
+ end
192
+
193
+ def value=(value)
194
+ fail ArgumentError, 'Value cannot be empty or nil' unless value && !value.empty?
195
+ self._value = value
196
+ end
197
+
198
+ def identifier_type=(value)
199
+ fail ArgumentError, 'Identifier type cannot be empty or nil' unless value
200
+ self._identifier_type = value
201
+ end
202
+
203
+ def relation_type=(value)
204
+ fail ArgumentError, 'Relation type cannot be nil' unless value
205
+ self._relation_type = value
206
+ end
207
+ end
208
+ end
209
+ end
@@ -0,0 +1,201 @@
1
+ require 'xml/mapping'
2
+ require_relative 'identifier'
3
+ require_relative 'creator'
4
+ require_relative 'title'
5
+ require_relative 'subject'
6
+ require_relative 'resource_type'
7
+ require_relative 'alternate_identifier'
8
+ require_relative 'related_identifier'
9
+ require_relative 'rights'
10
+
11
+ module Datacite
12
+ module Mapping
13
+
14
+ # A collection of metadata properties chosen for the accurate and consistent identification
15
+ # of a resource for citation and retrieval purposes, along with recommended use instructions.
16
+ # The resource that is being identified can be of any kind, but it is typically a dataset.
17
+ class Resource
18
+ include XML::Mapping
19
+
20
+ # @!attribute [rw] identifier
21
+ # @return [Identifier] a persistent identifier that identifies a resource.
22
+ object_node :identifier, 'identifier', class: Identifier
23
+
24
+ # @!attribute [rw] creators
25
+ # @return [Array<Creator>] the main researchers involved working on the data, or the authors of the publication in priority order.
26
+ array_node :creators, 'creators', 'creator', class: Creator
27
+
28
+ # @!attribute [rw] titles
29
+ # @return [Array<Title>] the names or titles by which a resource is known.
30
+ array_node :titles, 'titles', 'title', class: Title
31
+
32
+ # @!attribute [rw] publisher
33
+ # @return [String] the name of the entity that holds, archives, publishes prints, distributes, releases, issues, or produces the resource.
34
+ text_node :publisher, 'publisher'
35
+
36
+ # @!attribute [rw] publication_year
37
+ # @return [Integer] year when the resource is made publicly available.
38
+ numeric_node :publication_year, 'publicationYear'
39
+
40
+ # @!attribute [rw] subjects
41
+ # @return [Array<Subject>] subjects, keywords, classification codes, or key phrases describing the resource.
42
+ array_node :subjects, 'subjects', 'subject', class: Subject, default_value: []
43
+
44
+ # @!attribute [rw] contributors
45
+ # @return [Array<Contributor>] institutions or persons responsible for collecting, creating, or otherwise contributing to the developement of the dataset.
46
+ array_node :contributors, 'contributors', 'contributor', class: Contributor, default_value: []
47
+
48
+ # @!attribute [rw] dates
49
+ # @return [Array<Date>] different dates relevant to the work.
50
+ array_node :dates, 'dates', 'date', class: Date, default_value: []
51
+
52
+ # @!attribute [rw] language
53
+ # @return [String] Primary language of the resource: an IETF BCP 47, ISO 639-1 language code.
54
+ # It's unclear from the spec whether language is required; to play it safe, if it's missing, we default to 'en'.
55
+ text_node :language, 'language'
56
+
57
+ # @!attribute [rw] resource_type
58
+ # @return [ResourceType, nil] the type of the resource. Optional.
59
+ object_node :resource_type, 'resourceType', class: ResourceType, default_value: nil
60
+
61
+ # @!attribute [rw] alternate_identifiers
62
+ # @return [Array<AlternateIdentifier>] an identifier or identifiers other than the primary {Identifier} applied to the resource being registered.
63
+ array_node :alternate_identifiers, 'alternateIdentifiers', 'alternateIdentifier', class: AlternateIdentifier, default_value: []
64
+
65
+ # @!attribute [rw] related_identifiers
66
+ # @return [Array<RelatedIdentifier>] identifiers of related resources.
67
+ array_node :related_identifiers, 'relatedIdentifiers', 'relatedIdentifier', class: RelatedIdentifier, default_value: []
68
+
69
+ # @!attribute [rw] sizes
70
+ # @return [Array<String>] unstructured size information about the resource.
71
+ array_node :sizes, 'sizes', 'size', class: String, default_value: []
72
+
73
+ # @!attribute [rw] formats
74
+ # @return [Array<String>] technical format of the resource, e.g. file extension or MIME type.
75
+ array_node :formats, 'formats', 'format', class: String, default_value: []
76
+
77
+ # @!attribute [rw] version
78
+ # @return [String] version number of the resource. Optional.
79
+ text_node :version, 'version', default_value: nil
80
+
81
+ # @!attribute [rw] rights_list
82
+ # @return [Array<Rights>] rights information for this resource.
83
+ array_node :rights_list, 'rightsList', 'rights', class: Rights, default_value: []
84
+
85
+ # @!attribute [rw] descriptions
86
+ # @return [Array<Description>] all additional information that does not fit in any of the other categories.
87
+ array_node :descriptions, 'descriptions', 'description', class: Description, default_value: []
88
+
89
+ # @!attribute [rw] geo_locations
90
+ # @return [Array<GeoLocations>] spatial region or named place where the data was gathered or about which the data is focused.
91
+ array_node :geo_locations, 'geoLocations', 'geoLocation', class: GeoLocation, default_value: []
92
+
93
+ # Initialies a new {Resource}
94
+ #
95
+ # @param identifier [Identifier] a persistent identifier that identifies a resource.
96
+ # @param creators [Array<Creator>] the main researchers involved working on the data, or the authors of the publication in priority order.
97
+ # @param titles [Array<Title>] the names or titles by which a resource is known.
98
+ # @param publisher [String] the name of the entity that holds, archives, publishes prints, distributes, releases, issues, or produces the resource.
99
+ # @param publication_year [Integer] year when the resource is made publicly available.
100
+ # @param subjects [Array<Subject>] subjects, keywords, classification codes, or key phrases describing the resource.
101
+ # @param contributors [Array<Contributor>] institutions or persons responsible for collecting, creating, or otherwise contributing to the developement of the dataset.
102
+ # @param dates [Array<Date>] different dates relevant to the work.
103
+ # @param language [String] Primary language of the resource: an IETF BCP 47, ISO 639-1 language code.
104
+ # It's unclear from the spec whether language is required; to play it safe, if it's missing, we default to 'en'.
105
+ # @param resource_type [ResourceType, nil] the type of the resource
106
+ # @param alternate_identifiers [Array<AlternateIdentifier>] an identifier or identifiers other than the primary {Identifier} applied to the resource being registered.
107
+ # @param related_identifiers [Array<RelatedIdentifier>] identifiers of related resources.
108
+ # @param sizes [Array<String>] unstructured size information about the resource.
109
+ # @param formats [Array<String>] technical format of the resource, e.g. file extension or MIME type.
110
+ # @param version [String] version number of the resource.
111
+ # @param rights_list [Array<Rights>] rights information for this resource.
112
+ # @param descriptions [Array<Description>] all additional information that does not fit in any of the other categories.
113
+ # @param geo_locations [Array<GeoLocations>] spatial region or named place where the data was gathered or about which the data is focused.
114
+ def initialize(identifier:, creators:, titles:, publisher:, publication_year:, subjects: [], contributors: [], dates: [], language: 'en', resource_type: nil, alternate_identifiers: [], related_identifiers: [], sizes: [], formats: [], version: nil, rights_list: [], descriptions: [], geo_locations: []) # rubocop:disable Metrics/MethodLength, Metrics/ParameterLists, Metrics/AbcSize
115
+ self.identifier = identifier
116
+ self.creators = creators
117
+ self.titles = titles
118
+ self.publisher = publisher
119
+ self.publication_year = publication_year
120
+ self.subjects = subjects
121
+ self.contributors = contributors
122
+ self.dates = dates
123
+ self.language = language
124
+ self.resource_type = resource_type
125
+ self.alternate_identifiers = alternate_identifiers
126
+ self.related_identifiers = related_identifiers
127
+ self.sizes = sizes
128
+ self.formats = formats
129
+ self.version = version
130
+ self.rights_list = rights_list
131
+ self.descriptions = descriptions
132
+ self.geo_locations = geo_locations
133
+ end
134
+
135
+ alias_method :_language, :language
136
+ private :_language
137
+
138
+ alias_method :_language=, :language=
139
+ private :_language=
140
+
141
+ def language
142
+ _language || 'en'
143
+ end
144
+
145
+ def language=(value)
146
+ self._language = value.strip if value
147
+ end
148
+
149
+ alias_method :_identifier=, :identifier=
150
+ private :_identifier=
151
+
152
+ def identifier=(value)
153
+ fail ArgumentError, 'Resource must have an identifier' unless value
154
+ self._identifier = value
155
+ end
156
+
157
+ alias_method :_creators=, :creators=
158
+ private :_creators=
159
+
160
+ def creators=(value)
161
+ fail ArgumentError, 'Resource must have at least one creator' unless value && value.size > 0
162
+ self._creators = value
163
+ end
164
+
165
+ alias_method :_titles=, :titles=
166
+ private :_titles=
167
+
168
+ def titles=(value)
169
+ fail ArgumentError, 'Resource must have at least one title' unless value && value.size > 0
170
+ self._titles = value
171
+ end
172
+
173
+ alias_method :_publisher=, :publisher=
174
+ private :_publisher=
175
+
176
+ def publisher=(value)
177
+ fail ArgumentError, 'Resource must have at least one publisher' unless value && value.size > 0
178
+ self._publisher = value.strip
179
+ end
180
+
181
+ alias_method :_publication_year=, :publication_year=
182
+ private :_publication_year=
183
+
184
+ def publication_year=(value)
185
+ fail ArgumentError, 'Resource must have a four-digit publication year' unless value && value.to_i.between?(1000, 9999)
186
+ self._publication_year = value.to_i
187
+ end
188
+
189
+ # Overrides +::XML::Mapping.pre_save+ to write namespace information.
190
+ # Used for writing.
191
+ def pre_save(options = { mapping: :_default })
192
+ xml = super(options)
193
+ xml.add_namespace('http://datacite.org/schema/kernel-3')
194
+ xml.add_namespace('xsi', 'http://www.w3.org/2001/XMLSchema-instance')
195
+ xml.add_attribute('xsi:schemaLocation', 'http://datacite.org/schema/kernel-3 http://schema.datacite.org/meta/kernel-3/metadata.xsd')
196
+ xml
197
+ end
198
+
199
+ end
200
+ end
201
+ end