Module: Commonmeta::CrossrefUtils
- Included in:
- MetadataUtils
- Defined in:
- lib/commonmeta/crossref_utils.rb
Instance Method Summary collapse
- #crossref_errors(xml: nil) ⇒ Object
- #crossref_root_attributes ⇒ Object
- #insert_archive_locations(xml) ⇒ Object
- #insert_citation_list(xml) ⇒ Object
- #insert_crossref_abstract(xml) ⇒ Object
-
#insert_crossref_access_indicators(xml) ⇒ Object
xml.resourceType(types || types, ‘resourceTypeGeneral’ => types || Metadata::SO_TO_DC_TRANSLATIONS[types] || “Other”) end.
- #insert_crossref_anonymous(xml, contributor) ⇒ Object
- #insert_crossref_contributors(xml) ⇒ Object
- #insert_crossref_issn(xml) ⇒ Object
-
#insert_crossref_language(xml) ⇒ Object
xml.version(version_info) end.
- #insert_crossref_license(xml) ⇒ Object
- #insert_crossref_person(xml, contributor) ⇒ Object
- #insert_crossref_publication_date(xml) ⇒ Object
- #insert_crossref_relations(xml) ⇒ Object
- #insert_crossref_subjects(xml) ⇒ Object
- #insert_crossref_titles(xml) ⇒ Object
- #insert_crossref_work(xml) ⇒ Object
- #insert_doi_data(xml) ⇒ Object
-
#insert_funding_references(xml) ⇒ Object
xml.dates do Array.wrap(dates).each do |date| attributes = { ‘dateType’ => date || “Issued”, ‘dateInformation’ => date }.compact xml.date(date, attributes) end end end.
- #insert_group_title(xml) ⇒ Object
- #insert_institution(xml) ⇒ Object
- #insert_item_number(xml) ⇒ Object
- #insert_journal(xml) ⇒ Object
- #insert_posted_content(xml) ⇒ Object
- #insert_posted_date(xml) ⇒ Object
- #write_crossref_xml ⇒ Object
Instance Method Details
#crossref_errors(xml: nil) ⇒ Object
25 26 27 28 29 30 31 32 33 34 |
# File 'lib/commonmeta/crossref_utils.rb', line 25 def crossref_errors(xml: nil) filepath = File.("../../resources/crossref/crossref5.3.1.xsd", __dir__) File.open(filepath, "r") do |f| schema = Nokogiri::XML::Schema(f) end schema.validate(Nokogiri::XML(xml, nil, "UTF-8")).map(&:to_s).unwrap rescue Nokogiri::XML::SyntaxError => e e. end |
#crossref_root_attributes ⇒ Object
415 416 417 418 419 420 421 422 423 |
# File 'lib/commonmeta/crossref_utils.rb', line 415 def crossref_root_attributes { 'xmlns:xsi': "http://www.w3.org/2001/XMLSchema-instance", 'xsi:schemaLocation': "http://www.crossref.org/schema/5.3.1 https://www.crossref.org/schemas/crossref5.3.1.xsd", xmlns: "http://www.crossref.org/schema/5.3.1", 'xmlns:jats': "http://www.ncbi.nlm.nih.gov/JATS1", 'xmlns:fr': "http://www.crossref.org/fundref.xsd", 'xmlns:mml': "http://www.w3.org/1998/Math/MathML", version: "5.3.1" } end |
#insert_archive_locations(xml) ⇒ Object
331 332 333 334 335 336 337 338 339 |
# File 'lib/commonmeta/crossref_utils.rb', line 331 def insert_archive_locations(xml) return xml if archive_locations.blank? xml.archive_locations do archive_locations.each do |archive_location| xml.archive("name" => archive_location) end end end |
#insert_citation_list(xml) ⇒ Object
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/commonmeta/crossref_utils.rb', line 167 def insert_citation_list(xml) xml.citation_list do Array.wrap(references).each do |ref| xml.citation("key" => ref["key"]) do xml.journal_article(ref["journal_title"]) if ref["journal_title"].present? xml.(ref["author"]) if ref["author"].present? xml.volume(ref["volume"]) if ref["volume"].present? xml.first_page(ref["first_page"]) if ref["first_page"].present? xml.cYear(ref["publicationYear"]) if ref["publicationYear"].present? xml.article_title(ref["title"]) if ref["title"].present? xml.doi(doi_from_url(ref["doi"])) if ref["doi"].present? xml.unstructured_citation(ref["url"]) if ref["url"].present? end end end end |
#insert_crossref_abstract(xml) ⇒ Object
400 401 402 403 404 405 406 407 408 409 410 411 412 413 |
# File 'lib/commonmeta/crossref_utils.rb', line 400 def insert_crossref_abstract(xml) return xml if descriptions.blank? if descriptions.first.is_a?(Hash) d = descriptions.first else d = {} d["description"] = descriptions.first end xml.abstract("xmlns" => "http://www.ncbi.nlm.nih.gov/JATS1") do xml.p(d["description"]) end end |
#insert_crossref_access_indicators(xml) ⇒ Object
xml.resourceType(types || types,
'resourceTypeGeneral' => types["resourceTypeGeneral"] || Metadata::SO_TO_DC_TRANSLATIONS[types["schemaOrg"]] || "Other")
end
199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/commonmeta/crossref_utils.rb', line 199 def insert_crossref_access_indicators(xml) return xml if license.blank? rights_uri = license["url"] xml.program("xmlns" => "http://www.crossref.org/AccessIndicators.xsd", "name" => "AccessIndicators") do xml.license_ref(rights_uri, "applies_to" => "vor") xml.license_ref(rights_uri, "applies_to" => "tdm") end end |
#insert_crossref_anonymous(xml, contributor) ⇒ Object
146 147 148 149 150 151 152 153 |
# File 'lib/commonmeta/crossref_utils.rb', line 146 def insert_crossref_anonymous(xml, contributor) xml.affiliations do xml.institution do xml.institution_name(contributor.dig("affiliation", 0, "name")) if contributor.dig("affiliation", 0, "name").present? xml.institution_id(contributor.dig("affiliation", 0, "id"), "type" => "ror") if contributor.dig("affiliation", 0, "id").present? end end end |
#insert_crossref_contributors(xml) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/commonmeta/crossref_utils.rb', line 100 def insert_crossref_contributors(xml) return xml if contributors.blank? con = Array.wrap(contributors).select { |c| c["contributorRoles"] == ["Author"] || c["contributorRoles"] == ["Editor"] } xml.contributors do Array.wrap(con).each_with_index do |contributor, index| contributor_role = contributor["contributorRoles"] == ["Author"] ? "author" : "editor" if contributor["type"] == "Organization" && contributor["name"].present? xml.organization(contributor["name"], "contributor_role" => contributor_role, "sequence" => index.zero? ? "first" : "additional") elsif contributor["givenName"].present? || contributor["familyName"].present? xml.person_name("contributor_role" => contributor_role, "sequence" => index.zero? ? "first" : "additional") do insert_crossref_person(xml, contributor) end elsif contributor["affiliation"].present? xml.anonymous("contributor_role" => contributor_role, "sequence" => index.zero? ? "first" : "additional") do insert_crossref_anonymous(xml, contributor) end else xml.anonymous("contributor_role" => contributor_role, "sequence" => index.zero? ? "first" : "additional") end end end end |
#insert_crossref_issn(xml) ⇒ Object
390 391 392 393 394 395 396 397 398 |
# File 'lib/commonmeta/crossref_utils.rb', line 390 def insert_crossref_issn(xml) issn = if container.to_h.fetch("identifierType", nil) == "ISSN" container.to_h.fetch("identifier", nil) end return xml if issn.blank? xml.issn(issn) end |
#insert_crossref_language(xml) ⇒ Object
xml.version(version_info) end
278 279 280 281 282 |
# File 'lib/commonmeta/crossref_utils.rb', line 278 def insert_crossref_language(xml) return xml unless language.present? xml.language(language) end |
#insert_crossref_license(xml) ⇒ Object
365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 |
# File 'lib/commonmeta/crossref_utils.rb', line 365 def insert_crossref_license(xml) return xml unless license.present? xml.license do rights = license if rights.is_a?(Hash) r = rights else r = {} r["rights"] = rights r["rightsUri"] = normalize_id(rights) end attributes = { "rightsURI" => r["rightsUri"], "rightsIdentifier" => r["rightsIdentifier"], "rightsIdentifierScheme" => r["rightsIdentifierScheme"], "schemeURI" => r["schemeUri"], "xml:lang" => r["lang"], }.compact xml.rights(r["rights"], attributes) end end |
#insert_crossref_person(xml, contributor) ⇒ Object
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/commonmeta/crossref_utils.rb', line 130 def insert_crossref_person(xml, contributor) xml.given_name(contributor["givenName"]) if contributor["givenName"].present? xml.surname(contributor["familyName"]) if contributor["familyName"].present? if contributor.dig("id") && URI.parse(contributor.dig("id")).host == "orcid.org" xml.ORCID(contributor.dig("id")) end if contributor["affiliation"].present? xml.affiliations do xml.institution do xml.institution_name(contributor.dig("affiliation", 0, "name")) if contributor.dig("affiliation", 0, "name").present? xml.institution_id(contributor.dig("affiliation", 0, "id"), "type" => "ror") if contributor.dig("affiliation", 0, "id").present? end end end end |
#insert_crossref_publication_date(xml) ⇒ Object
284 285 286 287 288 289 290 291 292 293 294 |
# File 'lib/commonmeta/crossref_utils.rb', line 284 def insert_crossref_publication_date(xml) return xml if date["registered"].blank? date_ = get_datetime_from_iso8601(date["registered"]) xml.publication_date("media_type" => "online") do xml.month(date_.month) if date_.month.present? xml.day(date_.day) if date_.day.present? xml.year(date_.year) if date_.year.present? end end |
#insert_crossref_relations(xml) ⇒ Object
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/commonmeta/crossref_utils.rb', line 211 def insert_crossref_relations(xml) return xml if .blank? xml.program("xmlns" => "http://www.crossref.org/relations.xsd", "name" => "relations") do .each do || xml. do identifier_type = validate_doi(["id"]) ? "doi" : "uri" id = identifier_type == "doi" ? doi_from_url(["id"]) : ["id"] attributes = { "relationship-type" => ["type"].camelize(:lower), "identifier-type" => identifier_type, }.compact xml.intra_work_relation(id, attributes) end end end end |
#insert_crossref_subjects(xml) ⇒ Object
258 259 260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/commonmeta/crossref_utils.rb', line 258 def insert_crossref_subjects(xml) return xml unless subjects.present? xml.subjects do subjects.each do |subject| if subject.is_a?(Hash) xml.subject(subject["subject"]) else xml.subject(subject) end end end end |
#insert_crossref_titles(xml) ⇒ Object
155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/commonmeta/crossref_utils.rb', line 155 def insert_crossref_titles(xml) xml.titles do Array.wrap(titles).each do |title| if title.is_a?(Hash) xml.title(title["title"]) else xml.title(title) end end end end |
#insert_crossref_work(xml) ⇒ Object
36 37 38 39 40 41 42 43 44 45 |
# File 'lib/commonmeta/crossref_utils.rb', line 36 def insert_crossref_work(xml) return xml if doi_from_url(id).blank? case type when "JournalArticle" insert_journal(xml) when "Article" insert_posted_content(xml) end end |
#insert_doi_data(xml) ⇒ Object
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 |
# File 'lib/commonmeta/crossref_utils.rb', line 341 def insert_doi_data(xml) return xml if doi_from_url(id).blank? || url.blank? xml.doi_data do doi = doi_from_url(id).downcase xml.doi(doi) xml.resource(url) xml.collection("property" => "text-mining") do xml.item do xml.resource(url, "mime_type" => "text/html") end if is_rogue_scholar_doi?(doi) Array.wrap(files).each do |file| xml.item do # Crossref schema currently doesn't support text/markdown file["mimeType"] = "text/plain" if file["mimeType"] == "text/markdown" xml.resource(file["url"], "mime_type" => file["mimeType"]) end end end end end end |
#insert_funding_references(xml) ⇒ Object
xml.dates do
Array.wrap(dates).each do |date|
attributes = { 'dateType' => date["dateType"] || "Issued", 'dateInformation' => date["dateInformation"] }.compact
xml.date(date["date"], attributes)
end
end
end
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/commonmeta/crossref_utils.rb', line 242 def insert_funding_references(xml) return xml if funding_references.blank? xml.program("xmlns" => "http://www.crossref.org/fundref.xsd", "name" => "fundref") do funding_references.each do |funding_reference| xml.assertion("name" => "fundgroup") do xml.assertion(funding_reference["funderName"], "name" => "funder_name") do xml.assertion(funding_reference["funderIdentifier"], "name" => "funder_identifier") end xml.assertion(funding_reference["awardNumber"], "name" => "award_number") end end end end |
#insert_group_title(xml) ⇒ Object
94 95 96 97 98 |
# File 'lib/commonmeta/crossref_utils.rb', line 94 def insert_group_title(xml) return xml if subjects.blank? xml.group_title(subjects.first["subject"]) end |
#insert_institution(xml) ⇒ Object
308 309 310 311 312 313 314 |
# File 'lib/commonmeta/crossref_utils.rb', line 308 def insert_institution(xml) return xml if publisher.blank? xml.institution do xml.institution_name(publisher["name"]) end end |
#insert_item_number(xml) ⇒ Object
316 317 318 319 320 321 322 323 324 325 326 327 328 329 |
# File 'lib/commonmeta/crossref_utils.rb', line 316 def insert_item_number(xml) return xml if alternate_identifiers.blank? alternate_identifiers.each do |alternate_identifier| attributes = { "item_number_type" => alternate_identifier["alternateIdentifierType"] ? alternate_identifier["alternateIdentifierType"].downcase : nil, }.compact # strip hyphen from UUIDs, as item_number can only be 32 characters long (UUIDv4 is 36 characters long) alternate_identifier["alternateIdentifier"] = alternate_identifier["alternateIdentifier"].gsub("-", "") if alternate_identifier["alternateIdentifierType"] == "UUID" xml.item_number(alternate_identifier["alternateIdentifier"], attributes) end end |
#insert_journal(xml) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/commonmeta/crossref_utils.rb', line 47 def insert_journal(xml) xml.journal do if language.present? xml.("language" => language[0..1]) do xml.full_title(container["title"]) end else xml. do xml.full_title(container["title"]) end end xml.journal_article("publication_type" => "full_text") do insert_crossref_titles(xml) insert_crossref_contributors(xml) insert_crossref_publication_date(xml) insert_crossref_abstract(xml) insert_crossref_issn(xml) insert_item_number(xml) insert_funding_references(xml) insert_crossref_access_indicators(xml) insert_crossref_relations(xml) insert_archive_locations(xml) insert_doi_data(xml) insert_citation_list(xml) end end end |
#insert_posted_content(xml) ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/commonmeta/crossref_utils.rb', line 75 def insert_posted_content(xml) posted_content = { "type" => "other", "language" => language ? language[0..1] : nil }.compact xml.posted_content(posted_content) do insert_group_title(xml) insert_crossref_contributors(xml) insert_crossref_titles(xml) insert_posted_date(xml) insert_institution(xml) insert_item_number(xml) insert_crossref_abstract(xml) insert_funding_references(xml) insert_crossref_access_indicators(xml) insert_crossref_relations(xml) insert_doi_data(xml) insert_citation_list(xml) end end |
#insert_posted_date(xml) ⇒ Object
296 297 298 299 300 301 302 303 304 305 306 |
# File 'lib/commonmeta/crossref_utils.rb', line 296 def insert_posted_date(xml) return xml if date["published"].blank? date_ = get_datetime_from_iso8601(date["published"]) xml.posted_date do xml.month(date_.month) if date_.month.present? xml.day(date_.day) if date_.day.present? xml.year(date_.year) if date_.year.present? end end |
#write_crossref_xml ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/commonmeta/crossref_utils.rb', line 5 def write_crossref_xml @crossref_xml ||= Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml| xml.doi_batch(crossref_root_attributes) do xml.head do # we use a uuid as batch_id xml.doi_batch_id(SecureRandom.uuid) xml.(Time.now.utc.strftime("%Y%m%d%H%M%S")) xml.depositor do xml.depositor_name(depositor) xml.email_address(email) end xml.registrant(registrant) end xml.body do insert_crossref_work(xml) end end end.to_xml end |