relaton-iso-bib 0.9.2 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/grammars/basicdoc.rng +12 -56
- data/grammars/biblio.rng +145 -50
- data/grammars/isodoc.rng +1045 -55
- data/grammars/isostandard.rng +148 -472
- data/lib/relaton_iso_bib/hash_converter.rb +2 -69
- data/lib/relaton_iso_bib/iso_bibliographic_item.rb +20 -154
- data/lib/relaton_iso_bib/structured_identifier.rb +7 -4
- data/lib/relaton_iso_bib/version.rb +1 -1
- data/lib/relaton_iso_bib/xml_parser.rb +14 -28
- data/relaton_iso_bib.gemspec +5 -4
- metadata +4 -5
- data/lib/relaton_iso_bib/typed_title_string.rb +0 -32
@@ -1,75 +1,8 @@
|
|
1
1
|
module RelatonIsoBib
|
2
2
|
class HashConverter < RelatonBib::HashConverter
|
3
3
|
class << self
|
4
|
-
# @override RelatonBib::HashConverter.hash_to_bib
|
5
|
-
# @param args [Hash]
|
6
|
-
# @param nested [TrueClass, FalseClass]
|
7
|
-
# @return [Hash]
|
8
|
-
def hash_to_bib(args, nested = false)
|
9
|
-
ret = super
|
10
|
-
return if ret.nil?
|
11
|
-
|
12
|
-
editorialgroup_hash_to_bib(ret)
|
13
|
-
ics_hash_to_bib(ret)
|
14
|
-
structuredidentifier_hash_to_bib(ret)
|
15
|
-
ret
|
16
|
-
end
|
17
|
-
|
18
|
-
def split_title(content, lang = "en", script = "Latn")
|
19
|
-
titles = content&.split(/ (?:--|—|–) /)
|
20
|
-
case titles&.size
|
21
|
-
when nil, 0
|
22
|
-
intro, main, part = nil, "", nil
|
23
|
-
when 1
|
24
|
-
intro, main, part = nil, titles[0], nil
|
25
|
-
when 2
|
26
|
-
if /^(Part|Partie) \d+:/ =~ titles[1]
|
27
|
-
intro, main, part = nil, titles[0], titles[1]
|
28
|
-
else
|
29
|
-
intro, main, part = titles[0], titles[1], nil
|
30
|
-
end
|
31
|
-
when 3
|
32
|
-
intro, main, part = titles[0], titles[1], titles[2]
|
33
|
-
else
|
34
|
-
intro, main, part = titles[0], titles[1], titles[2..-1]&.join(" -- ")
|
35
|
-
end
|
36
|
-
{
|
37
|
-
title_intro: intro,
|
38
|
-
title_main: main,
|
39
|
-
title_part: part,
|
40
|
-
language: lang,
|
41
|
-
script: script,
|
42
|
-
}
|
43
|
-
end
|
44
|
-
|
45
4
|
private
|
46
5
|
|
47
|
-
#
|
48
|
-
# Ovverides superclass's method
|
49
|
-
#
|
50
|
-
# @param ret [Hash]
|
51
|
-
def title_hash_to_bib(ret)
|
52
|
-
return unless ret[:title]
|
53
|
-
|
54
|
-
ret[:title] = array(ret[:title])
|
55
|
-
ret[:title] = ret[:title].reduce([]) do |a, t|
|
56
|
-
if t.is_a?(String)
|
57
|
-
a << split_title(t)
|
58
|
-
elsif t.is_a?(Hash) && t[:type]
|
59
|
-
idx = a.index { |i| i[:language] == t[:language] }
|
60
|
-
title_key = t[:type].sub("-", "_").to_sym
|
61
|
-
if idx
|
62
|
-
a[idx][title_key] = t[:content]
|
63
|
-
a
|
64
|
-
else
|
65
|
-
a << { title_key => t[:content], language: t[:language], script: t[:script] }
|
66
|
-
end
|
67
|
-
elsif t.is_a?(Hash) && t[:content]
|
68
|
-
a << split_title(t[:content], t[:language], t[:script])
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
6
|
#
|
74
7
|
# Ovverides superclass's method
|
75
8
|
#
|
@@ -83,9 +16,9 @@ module RelatonIsoBib
|
|
83
16
|
# Ovverides superclass's method
|
84
17
|
#
|
85
18
|
# @param title [Hash]
|
86
|
-
# @return [
|
19
|
+
# @return [RelatonBib::TypedTitleString]
|
87
20
|
def typed_title_strig(title)
|
88
|
-
TypedTitleString.new title
|
21
|
+
RelatonBib::TypedTitleString.new title
|
89
22
|
end
|
90
23
|
|
91
24
|
# @param ret [Hash]
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require "nokogiri"
|
4
4
|
require "isoics"
|
5
5
|
require "relaton_bib"
|
6
|
-
require "relaton_iso_bib/typed_title_string"
|
6
|
+
# require "relaton_iso_bib/typed_title_string"
|
7
7
|
require "relaton_iso_bib/editorial_group"
|
8
8
|
require "relaton_iso_bib/xml_parser"
|
9
9
|
require "relaton_iso_bib/structured_identifier"
|
@@ -23,19 +23,19 @@ module RelatonIsoBib
|
|
23
23
|
# Bibliographic item.
|
24
24
|
class IsoBibliographicItem < RelatonBib::BibliographicItem
|
25
25
|
TYPES = %w[
|
26
|
-
standard
|
27
26
|
international-standard technical-specification technical-report
|
28
27
|
publicly-available-specification international-workshop-agreement guide
|
28
|
+
amendment technical-corrigendum
|
29
29
|
].freeze
|
30
30
|
|
31
31
|
# @return [RelatonIsoBib::StructuredIdentifier]
|
32
32
|
attr_reader :structuredidentifier
|
33
33
|
|
34
34
|
# @!attribute [r] title
|
35
|
-
# @return [Array<
|
35
|
+
# @return [Array<RelatonBib::TypedTitleString>]
|
36
36
|
|
37
37
|
# @return [String, NilClass]
|
38
|
-
attr_reader :doctype
|
38
|
+
attr_reader :doctype, :stagename
|
39
39
|
|
40
40
|
# @return [RelatonIsoBib::EditorialGroup]
|
41
41
|
attr_reader :editorialgroup
|
@@ -43,9 +43,6 @@ module RelatonIsoBib
|
|
43
43
|
# @return [Array<RelatonIsoBib::Ics>]
|
44
44
|
attr_reader :ics
|
45
45
|
|
46
|
-
# @return [TrueClass, FalseClass, NilClass]
|
47
|
-
attr_accessor :all_parts
|
48
|
-
|
49
46
|
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
50
47
|
# rubocop:disable Metrics/MethodLength, Metrics/PerceivedComplexity
|
51
48
|
|
@@ -67,6 +64,7 @@ module RelatonIsoBib
|
|
67
64
|
# @param validity [RelatonBib:Validity, NilClass]
|
68
65
|
# @param docid [Array<RelatonBib::DocumentIdentifier>]
|
69
66
|
# @param structuredidentifier [RelatonIsoBib::StructuredIdentifier]
|
67
|
+
# @param stagename [String, NilClass]
|
70
68
|
#
|
71
69
|
# @param title [Array<Hash>]
|
72
70
|
# @option title [String] :title_intro
|
@@ -75,7 +73,7 @@ module RelatonIsoBib
|
|
75
73
|
# @option title [String] :language
|
76
74
|
# @option title [String] :script
|
77
75
|
#
|
78
|
-
# @param editorialgroup [Hash, RelatonIsoBib::EditorialGroup
|
76
|
+
# @param editorialgroup [Hash, RelatonIsoBib::EditorialGroup]
|
79
77
|
# @option workgrpup [String] :name
|
80
78
|
# @option workgrpup [String] :abbreviation
|
81
79
|
# @option workgrpup [String] :url
|
@@ -127,24 +125,23 @@ module RelatonIsoBib
|
|
127
125
|
# @raise [ArgumentError]
|
128
126
|
def initialize(**args)
|
129
127
|
check_doctype args[:doctype]
|
130
|
-
# check_language args.fetch(:language, [])
|
131
|
-
# check_script args.fetch(:script, [])
|
132
128
|
|
133
129
|
super_args = args.select do |k|
|
134
130
|
%i[id docnumber language script docstatus date abstract contributor
|
135
131
|
edition version relation biblionote series medium place copyright
|
136
132
|
link fetched docid formattedref extent accesslocation classification
|
137
|
-
validity keyword].include? k
|
133
|
+
validity doctype keyword].include? k
|
138
134
|
end
|
139
135
|
super super_args
|
140
136
|
|
141
137
|
@type = args[:type] || "standard"
|
142
138
|
|
143
|
-
@title = args.fetch(:title, []).
|
139
|
+
@title = args.fetch(:title, []).map do |t|
|
144
140
|
if t.is_a? Hash
|
145
|
-
a + typed_titles(t)
|
141
|
+
# a + typed_titles(t)
|
142
|
+
RelatonBib::TypedTitleString.new t
|
146
143
|
else
|
147
|
-
|
144
|
+
t
|
148
145
|
end
|
149
146
|
end
|
150
147
|
|
@@ -156,81 +153,11 @@ module RelatonIsoBib
|
|
156
153
|
end
|
157
154
|
|
158
155
|
@structuredidentifier = args[:structuredidentifier]
|
159
|
-
@doctype
|
156
|
+
# @doctype = args[:doctype] || "international-standard"
|
160
157
|
@ics = args.fetch(:ics, []).map { |i| i.is_a?(Hash) ? Ics.new(i) : i }
|
158
|
+
@stagename = args[:stagename]
|
161
159
|
@id_attribute = true
|
162
160
|
end
|
163
|
-
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
164
|
-
# rubocop:enable Metrics/MethodLength, Metrics/PerceivedComplexity
|
165
|
-
|
166
|
-
def disable_id_attribute
|
167
|
-
@id_attribute = false
|
168
|
-
end
|
169
|
-
|
170
|
-
# remove title part components and abstract
|
171
|
-
def to_all_parts
|
172
|
-
me = deep_clone
|
173
|
-
me.disable_id_attribute
|
174
|
-
me.relation << RelatonBib::DocumentRelation.new(
|
175
|
-
type: "instance", bibitem: self,
|
176
|
-
)
|
177
|
-
me.language.each do |l|
|
178
|
-
me.title.delete_if { |t| t.type == "title-part" }
|
179
|
-
ttl = me.title.select { |t| t.type != "main" && t.title.language.include?(l) }
|
180
|
-
tm_en = ttl.map { |t| t.title.content }.join " – "
|
181
|
-
me.title.detect { |t| t.type == "main" && t.title.language.include?(l) }&.title&.content = tm_en
|
182
|
-
end
|
183
|
-
me.abstract = []
|
184
|
-
me.docidentifier.each(&:remove_part)
|
185
|
-
me.docidentifier.each(&:all_parts)
|
186
|
-
me.structuredidentifier.remove_part
|
187
|
-
me.structuredidentifier.all_parts
|
188
|
-
me.docidentifier.each &:remove_date
|
189
|
-
me.structuredidentifier&.remove_date
|
190
|
-
me.all_parts = true
|
191
|
-
me
|
192
|
-
end
|
193
|
-
|
194
|
-
def abstract=(value)
|
195
|
-
@abstract = value
|
196
|
-
end
|
197
|
-
|
198
|
-
def deep_clone
|
199
|
-
dump = Marshal.dump self
|
200
|
-
Marshal.load dump
|
201
|
-
end
|
202
|
-
|
203
|
-
# convert ISO:yyyy reference to reference to most recent
|
204
|
-
# instance of reference, removing date-specific infomration:
|
205
|
-
# date of publication, abstracts. Make dated reference Instance relation
|
206
|
-
# of the redacated document
|
207
|
-
def to_most_recent_reference
|
208
|
-
me = deep_clone
|
209
|
-
self.disable_id_attribute
|
210
|
-
me.relation << RelatonBib::DocumentRelation.new(type: "instance", bibitem: self)
|
211
|
-
me.abstract = []
|
212
|
-
me.date = []
|
213
|
-
me.docidentifier.each &:remove_date
|
214
|
-
me.structuredidentifier&.remove_date
|
215
|
-
me.id&.sub! /-[12]\d\d\d/, ""
|
216
|
-
me
|
217
|
-
end
|
218
|
-
|
219
|
-
# @param lang [String] language code Iso639
|
220
|
-
# @return [Array<RelatonIsoBib::TypedTitleString>]
|
221
|
-
def title(lang: nil)
|
222
|
-
if lang
|
223
|
-
@title.select { |t| t.title.language.include? lang }
|
224
|
-
else
|
225
|
-
@title
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
|
-
# @param type [Symbol] type of url, can be :src/:obp/:rss
|
230
|
-
# @return [String]
|
231
|
-
def url(type = :src)
|
232
|
-
@link.detect { |s| s.type == type.to_s }.content.to_s
|
233
|
-
end
|
234
161
|
|
235
162
|
# @return [String]
|
236
163
|
def to_xml(builder = nil, **opts, &block)
|
@@ -243,7 +170,8 @@ module RelatonIsoBib
|
|
243
170
|
end
|
244
171
|
super builder, **opts do |b|
|
245
172
|
if opts[:bibdata] && (doctype || respond_to?(:committee) && committee ||
|
246
|
-
editorialgroup || ics.any? || structuredidentifier ||
|
173
|
+
editorialgroup || ics.any? || structuredidentifier || stagename ||
|
174
|
+
block_given?)
|
247
175
|
b.ext do
|
248
176
|
b.doctype doctype if doctype
|
249
177
|
b.docsubtype docsubtype if respond_to?(:docsubtype) && docsubtype
|
@@ -255,42 +183,27 @@ module RelatonIsoBib
|
|
255
183
|
end
|
256
184
|
ics.each { |i| i.to_xml b }
|
257
185
|
structuredidentifier&.to_xml b
|
186
|
+
b.stagename stagename if stagename
|
258
187
|
yield b if block_given?
|
259
188
|
end
|
260
189
|
end
|
261
190
|
end
|
262
191
|
end
|
263
192
|
|
193
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
194
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
195
|
+
|
264
196
|
# @return [Hash]
|
265
197
|
def to_hash
|
266
198
|
hash = super
|
267
199
|
hash["editorialgroup"] = editorialgroup.to_hash if editorialgroup
|
268
200
|
hash["ics"] = single_element_array(ics) if ics&.any?
|
269
|
-
hash["
|
270
|
-
hash["doctype"] = doctype if doctype
|
201
|
+
hash["stagename"] = stagename if stagename
|
271
202
|
hash
|
272
203
|
end
|
273
204
|
|
274
205
|
private
|
275
206
|
|
276
|
-
# @param language [Array<String>]
|
277
|
-
# @raise ArgumentError
|
278
|
-
# def check_language(language)
|
279
|
-
# language.each do |lang|
|
280
|
-
# unless %w[en fr].include? lang
|
281
|
-
# raise ArgumentError, "invalid language: #{lang}"
|
282
|
-
# end
|
283
|
-
# end
|
284
|
-
# end
|
285
|
-
|
286
|
-
# @param script [Array<String>]
|
287
|
-
# @raise ArgumentError
|
288
|
-
# def check_script(script)
|
289
|
-
# script.each do |scr|
|
290
|
-
# raise ArgumentError, "invalid script: #{scr}" unless scr == "Latn"
|
291
|
-
# end
|
292
|
-
# end
|
293
|
-
|
294
207
|
# @param doctype [String]
|
295
208
|
# @raise ArgumentError
|
296
209
|
def check_doctype(doctype)
|
@@ -299,64 +212,17 @@ module RelatonIsoBib
|
|
299
212
|
end
|
300
213
|
end
|
301
214
|
|
302
|
-
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
303
|
-
|
304
|
-
# @param title [Hash]
|
305
|
-
# @option title [String] :title_intro
|
306
|
-
# @option title [String] :title_main
|
307
|
-
# @option title [String] :title_part
|
308
|
-
# @option title [String] :language
|
309
|
-
# @option title [String] :script
|
310
|
-
# @return [Array<RelatonIsoBib::TypedTitleStrig>]
|
311
|
-
def typed_titles(title)
|
312
|
-
titles = []
|
313
|
-
if title[:title_intro]
|
314
|
-
titles << TypedTitleString.new(
|
315
|
-
type: "title-intro", content: title[:title_intro],
|
316
|
-
language: title[:language], script: title[:script], format: "text/plain",
|
317
|
-
)
|
318
|
-
end
|
319
|
-
|
320
|
-
if title[:title_main]
|
321
|
-
titles << TypedTitleString.new(
|
322
|
-
type: "title-main", content: title[:title_main],
|
323
|
-
language: title[:language], script: title[:script], format: "text/plain",
|
324
|
-
)
|
325
|
-
end
|
326
|
-
|
327
|
-
if title[:title_part]
|
328
|
-
titles << TypedTitleString.new(
|
329
|
-
type: "title-part", content: title[:title_part],
|
330
|
-
language: title[:language], script: title[:script], format: "text/plain",
|
331
|
-
)
|
332
|
-
end
|
333
|
-
|
334
|
-
unless titles.empty?
|
335
|
-
titles << TypedTitleString.new(
|
336
|
-
type: "main", content: titles.map { |t| t.title.content }.join(" – "),
|
337
|
-
language: title[:language], script: title[:script], format: "text/plain",
|
338
|
-
)
|
339
|
-
end
|
340
|
-
|
341
|
-
titles
|
342
|
-
end
|
343
|
-
|
344
215
|
def makeid(id, attribute, _delim = "")
|
345
216
|
return nil if attribute && !@id_attribute
|
346
217
|
|
347
218
|
id ||= @docidentifier.reject { |i| i&.type == "DOI" }[0]
|
348
|
-
# contribs = publishers.map { |p| p&.entity&.abbreviation }.join '/'
|
349
|
-
# idstr = "#{contribs}#{delim}#{id.project_number}"
|
350
|
-
# idstr = id.project_number.to_s
|
351
219
|
if id
|
352
220
|
idstr = id.id
|
353
221
|
idstr = "IEV" if structuredidentifier&.project_number == "IEV"
|
354
222
|
else
|
355
223
|
idstr = formattedref&.content
|
356
224
|
end
|
357
|
-
# if id.part_number&.size&.positive? then idstr += "-#{id.part_number}"
|
358
225
|
idstr&.gsub(/:/, "-")&.gsub(/\s/, "")&.strip
|
359
226
|
end
|
360
|
-
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
361
227
|
end
|
362
228
|
end
|
@@ -26,7 +26,6 @@ module RelatonIsoBib
|
|
26
26
|
@project_number = args[:project_number]
|
27
27
|
@part = args[:part]
|
28
28
|
@subpart = args[:subpart]
|
29
|
-
# @prefix = args[:prefix]
|
30
29
|
@type = args[:type]
|
31
30
|
end
|
32
31
|
|
@@ -42,10 +41,10 @@ module RelatonIsoBib
|
|
42
41
|
end
|
43
42
|
|
44
43
|
def remove_date
|
45
|
-
|
46
|
-
|
44
|
+
if @type == "Chinese Standard"
|
45
|
+
@project_number.sub!(/-[12]\d\d\d/, "")
|
47
46
|
else
|
48
|
-
@project_number
|
47
|
+
@project_number.sub!(/:[12]\d\d\d/, "")
|
49
48
|
end
|
50
49
|
end
|
51
50
|
|
@@ -78,5 +77,9 @@ module RelatonIsoBib
|
|
78
77
|
hash["type"] = type if type
|
79
78
|
hash
|
80
79
|
end
|
80
|
+
|
81
|
+
def presence?
|
82
|
+
true
|
83
|
+
end
|
81
84
|
end
|
82
85
|
end
|
@@ -3,20 +3,6 @@ require "nokogiri"
|
|
3
3
|
module RelatonIsoBib
|
4
4
|
class XMLParser < RelatonBib::XMLParser
|
5
5
|
class << self
|
6
|
-
# Override RelatonBib::XMLParser.form_xml method.
|
7
|
-
# @param xml [String]
|
8
|
-
# @return [RelatonIsoBib::IsoBibliographicItem]
|
9
|
-
def from_xml(xml)
|
10
|
-
doc = Nokogiri::XML(xml)
|
11
|
-
doc.remove_namespaces!
|
12
|
-
isoitem = doc.at "/bibitem|/bibdata"
|
13
|
-
if isoitem
|
14
|
-
IsoBibliographicItem.new item_data(isoitem)
|
15
|
-
else
|
16
|
-
warn "[relato-iso-bib] can't find bibitem or bibdata element in the XML"
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
6
|
private
|
21
7
|
|
22
8
|
# Override RelatonBib::XMLParser.item_data method.
|
@@ -29,15 +15,22 @@ module RelatonIsoBib
|
|
29
15
|
|
30
16
|
data[:doctype] = ext.at("./doctype")&.text
|
31
17
|
data[:editorialgroup] = fetch_editorialgroup ext
|
32
|
-
data[:ics] = fetch_ics ext
|
33
18
|
data[:structuredidentifier] = fetch_structuredidentifier ext
|
19
|
+
data[:stagename] = ext.at("./stagename")&.text
|
34
20
|
data
|
35
21
|
end
|
36
22
|
|
23
|
+
# override RelatonBib::BibliographicItem.bib_item method
|
24
|
+
# @param item_hash [Hash]
|
25
|
+
# @return [RelatonIsoBib::IsoBibliographicItem]
|
26
|
+
def bib_item(item_hash)
|
27
|
+
IsoBibliographicItem.new item_hash
|
28
|
+
end
|
29
|
+
|
37
30
|
# @param ext [Nokogiri::XML::Element]
|
38
31
|
# @return [RelatonIsoBib::StructuredIdentifier]
|
39
32
|
def fetch_structuredidentifier(ext)
|
40
|
-
sid = ext
|
33
|
+
sid = ext&.at "./structuredidentifier"
|
41
34
|
return unless sid
|
42
35
|
|
43
36
|
pn = sid.at "project-number"
|
@@ -50,36 +43,29 @@ module RelatonIsoBib
|
|
50
43
|
|
51
44
|
# Override RelatonBib::XMLParser.ttitle method.
|
52
45
|
# @param title [Nokogiri::XML::Element]
|
53
|
-
# @return [
|
46
|
+
# @return [RelatonBib::TypedTitleString]
|
54
47
|
def ttitle(title)
|
55
48
|
return unless title
|
56
49
|
|
57
|
-
TypedTitleString.new(
|
50
|
+
RelatonBib::TypedTitleString.new(
|
58
51
|
type: title[:type], content: title.text, language: title[:language],
|
59
52
|
script: title[:script], format: title[:format]
|
60
53
|
)
|
61
54
|
end
|
62
55
|
|
63
|
-
# @param item [Nokogiri::XML::Element]
|
64
|
-
# @return [Array<RelatonIsoBib::Ics>]
|
65
|
-
def fetch_ics(ext)
|
66
|
-
ext.xpath("./ics/code").map { |ics| Ics.new ics.text }
|
67
|
-
end
|
68
|
-
|
69
56
|
# @TODO Organization doesn't recreated
|
70
57
|
# @param ext [Nokogiri::XML::Element]
|
71
58
|
# @return [RelatonIsoBib::EditorialGroup]
|
72
59
|
def fetch_editorialgroup(ext)
|
73
|
-
eg = ext
|
60
|
+
eg = ext&.at("./editorialgroup")
|
74
61
|
return unless eg
|
75
62
|
|
76
63
|
tc = eg&.xpath("technical-committee")&.map { |t| iso_subgroup(t) }
|
77
64
|
sc = eg&.xpath("subcommittee")&.map { |s| iso_subgroup(s) }
|
78
65
|
wg = eg&.xpath("workgroup")&.map { |w| iso_subgroup(w) }
|
79
66
|
sr = eg&.at "secretariat"
|
80
|
-
EditorialGroup.new(
|
81
|
-
|
82
|
-
)
|
67
|
+
EditorialGroup.new(technical_committee: tc, subcommittee: sc,
|
68
|
+
workgroup: wg, secretariat: sr&.text)
|
83
69
|
end
|
84
70
|
|
85
71
|
# @param com [Nokogiri::XML::Element]
|