libis-tools 0.9.6 → 0.9.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/libis/tools/config_file.rb +18 -13
- data/lib/libis/tools/metadata/dublin_core_record.rb +95 -0
- data/lib/libis/tools/metadata/field_spec.rb +81 -0
- data/lib/libis/tools/metadata/fix_field.rb +25 -0
- data/lib/libis/tools/metadata/marc21_record.rb +49 -0
- data/lib/libis/tools/metadata/marc_record.rb +209 -0
- data/lib/libis/tools/{sharepoint_mapping.rb → metadata/sharepoint_mapping.rb} +0 -0
- data/lib/libis/tools/{sharepoint_record.rb → metadata/sharepoint_record.rb} +0 -0
- data/lib/libis/tools/metadata/var_field.rb +224 -0
- data/lib/libis/tools/version.rb +1 -1
- data/lib/libis/tools/xml_document.rb +28 -12
- data/lib/libis/tools.rb +2 -0
- data/spec/config_file_spec.rb +39 -0
- data/spec/metadata/dublin_core_spec.rb +81 -0
- data/spec/xmldocument_spec.rb +10 -2
- metadata +12 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e717837dc7e2b3f0549cf1b6abf6ca1240f1344
|
4
|
+
data.tar.gz: 8310be003731268e303dd930279638d61b6a5edf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8fce8638e6fc55803704fda53975fedce79a0ed127c2c8e2cf7dd8b989e6d87af001a56205d1091865764c5fa99dc864dd473dd23df637b24e305f29d49d8df0
|
7
|
+
data.tar.gz: 8b8f8b6b0af625240709d68fd48ea75003c7fe8dbf460cdaecd4d67d6f8a2a19a9aad07daae54ab9602237769ec118807eeb6d92107b34c64d48fcb9af15ad48
|
@@ -34,8 +34,7 @@ module Libis
|
|
34
34
|
#
|
35
35
|
# @param [String,Hash] file_or_hash optional String or Hash argument to initialize the data.
|
36
36
|
def initialize(file_or_hash = nil, opt = {})
|
37
|
-
super(
|
38
|
-
self << file_or_hash
|
37
|
+
super _file_to_hash(file_or_hash), opt
|
39
38
|
end
|
40
39
|
|
41
40
|
# Load configuration parameters from a YAML file or Hash.
|
@@ -48,7 +47,21 @@ module Libis
|
|
48
47
|
#
|
49
48
|
# @param [String,Hash] file_or_hash optional String or Hash argument to initialize the data.
|
50
49
|
def <<(file_or_hash)
|
51
|
-
|
50
|
+
_file_to_hash(file_or_hash).each { |key, value| self[key] = value }
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
# Save configuration parameters in a YAML file.
|
55
|
+
#
|
56
|
+
# @param [String] file path of the YAML file to save the configuration to.
|
57
|
+
def >>(file)
|
58
|
+
File.open(file, 'w') { |f| f.write to_hash.to_yaml }
|
59
|
+
end
|
60
|
+
|
61
|
+
protected
|
62
|
+
|
63
|
+
def _file_to_hash(file_or_hash)
|
64
|
+
return {} if file_or_hash.nil? || (file_or_hash.respond_to?(:empty?) && file_or_hash.empty?)
|
52
65
|
hash = case file_or_hash
|
53
66
|
when Hash
|
54
67
|
yield file_or_hash if block_given?
|
@@ -61,16 +74,8 @@ module Libis
|
|
61
74
|
else
|
62
75
|
{}
|
63
76
|
end
|
64
|
-
|
65
|
-
hash
|
66
|
-
self
|
67
|
-
end
|
68
|
-
|
69
|
-
# Save configuration parameters in a YAML file.
|
70
|
-
#
|
71
|
-
# @param [String] file path of the YAML file to save the configuration to.
|
72
|
-
def >>(file)
|
73
|
-
File.open(file, 'w') { |f| f.write to_hash.to_yaml }
|
77
|
+
hash = {} unless hash.is_a? Hash
|
78
|
+
hash
|
74
79
|
end
|
75
80
|
|
76
81
|
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'nori'
|
3
|
+
require 'libis/tools/assert'
|
4
|
+
|
5
|
+
module Libis
|
6
|
+
module Tools
|
7
|
+
module Metadata
|
8
|
+
|
9
|
+
class DublinCoreRecord < Libis::Tools::XmlDocument
|
10
|
+
|
11
|
+
DC_ELEMENTS = %w'contributor coverage creator date description format identifier language' +
|
12
|
+
%w'publisher relation rights source subject title type'
|
13
|
+
DCTERMS_ELEMENTS = %w'abstract accessRights accrualMethod accrualPeriodicity accrualPolicy alternative' +
|
14
|
+
%w'audience available bibliographicCitation conformsTo contributor coverage created creator date' +
|
15
|
+
%w'dateAccepted dateCopyrighted dateSubmitted description educationLevel extent format hasFormat' +
|
16
|
+
%w'hasPart hasVersion identifier instructionalMethod isFormatOf isPartOf isReferencedBy isReplacedBy' +
|
17
|
+
%w'isRequiredBy issued isVersionOf language license mediator medium modified provenance publisher' +
|
18
|
+
%w'references relation replaces requires rights rightsHolder source spatial subject tableOfContents' +
|
19
|
+
%w'temporal title type valid'
|
20
|
+
|
21
|
+
def initialize(doc = nil)
|
22
|
+
super()
|
23
|
+
xml_doc = case doc
|
24
|
+
when ::Libis::Tools::XmlDocument
|
25
|
+
doc
|
26
|
+
when String
|
27
|
+
# noinspection RubyResolve
|
28
|
+
File.exist?(doc) ? Libis::Tools::XmlDocument.load(doc) : Libis::Tools::XmlDocument.parse(doc)
|
29
|
+
when IO
|
30
|
+
Libis::Tools::XmlDocument.parse(doc.read)
|
31
|
+
when Hash
|
32
|
+
Libis::Tools::XmlDocument.from_hash(doc)
|
33
|
+
when NilClass
|
34
|
+
Libis::Tools::XmlDocument.new.build do |xml|
|
35
|
+
xml.record('xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
36
|
+
'xmlns:dc' => 'http://purl.org/dc/elements/1.1/',
|
37
|
+
'xmlns:dcterms' => 'http://purl.org/dc/terms/') {
|
38
|
+
yield xml
|
39
|
+
}
|
40
|
+
end
|
41
|
+
else
|
42
|
+
raise ArgumentError, "Invalid argument: #{doc.inspect}"
|
43
|
+
end
|
44
|
+
@document = xml_doc.document if xml_doc
|
45
|
+
end
|
46
|
+
|
47
|
+
def all
|
48
|
+
@all_records ||= get_all_records
|
49
|
+
end
|
50
|
+
|
51
|
+
def xpath(path)
|
52
|
+
m = /^([\/.]*\/)?(dc(terms)?:)?(.*)/.match(path.to_s)
|
53
|
+
return [] unless m[4]
|
54
|
+
path = (m[1] || '') + ('dc:' || m[2]) + m[4]
|
55
|
+
raise ArgumentError, 'XML document not valid.' if self.invalid?
|
56
|
+
@document.xpath(path.to_s)
|
57
|
+
end
|
58
|
+
|
59
|
+
def add_node(name, value = nil, parent = nil, attributes = {})
|
60
|
+
ns, tag = get_namespace(name.to_s)
|
61
|
+
(attributes[:namespaces] ||= {})[:node_ns] ||= ns if ns
|
62
|
+
super tag, value, parent, attributes
|
63
|
+
end
|
64
|
+
|
65
|
+
protected
|
66
|
+
|
67
|
+
def get_nodes(tag, parent = nil)
|
68
|
+
parent ||= root
|
69
|
+
m = /^([\/\.]*\/)?(dc(?:terms)?:)?(.*)/.match(tag.to_s)
|
70
|
+
return [] unless m[3]
|
71
|
+
path = (m[1] || '') + ('dc:' || m[2]) + m[3]
|
72
|
+
parent.xpath(path)
|
73
|
+
end
|
74
|
+
|
75
|
+
def get_namespace(tag)
|
76
|
+
m = /^((dc)?(terms)?(?:_|:)?)?([a-zA-Z_][-_.0-9a-zA-Z]+)(.*)/.match tag
|
77
|
+
ns = if m[1].nil?
|
78
|
+
if DC_ELEMENTS.include?(m[4])
|
79
|
+
:dc
|
80
|
+
else
|
81
|
+
DCTERMS_ELEMENTS.include?(m[4]) ? :dcterms : nil
|
82
|
+
end
|
83
|
+
elsif m[3].nil?
|
84
|
+
:dc
|
85
|
+
else
|
86
|
+
:dcterms
|
87
|
+
end
|
88
|
+
[ns, "#{m[4]}#{m[5]}"]
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Libis
|
4
|
+
module Tools
|
5
|
+
module Metadata
|
6
|
+
|
7
|
+
class FieldSpec
|
8
|
+
|
9
|
+
attr_accessor :parts
|
10
|
+
attr_accessor :prefix
|
11
|
+
attr_accessor :join
|
12
|
+
attr_accessor :postfix
|
13
|
+
|
14
|
+
def initialize(*parts)
|
15
|
+
@parts = []
|
16
|
+
self[*parts]
|
17
|
+
end
|
18
|
+
|
19
|
+
def add_options(options = {})
|
20
|
+
if options[:fix]
|
21
|
+
if options[:fix].size == 2
|
22
|
+
@prefix, @postfix = options[:fix].split('')
|
23
|
+
else
|
24
|
+
@prefix, @postfix = options[:fix].split('|')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
@join = options[:join] if options[:join]
|
28
|
+
@prefix = FieldSpec::from(options[:prefix]) if options[:prefix]
|
29
|
+
@postfix = FieldSpec::from(options[:postfix]) if options[:postfix]
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
def add_default_options(options = {})
|
34
|
+
options.delete(:prefix) if @prefix
|
35
|
+
options.delete(:postfix) if @postfix
|
36
|
+
options.delete(:fix) if @prefix or @postfix
|
37
|
+
options.delete(:join) if @join
|
38
|
+
add_options options
|
39
|
+
end
|
40
|
+
|
41
|
+
def [](*parts)
|
42
|
+
options = parts.last.is_a?(Hash) ? parts.pop : {}
|
43
|
+
parts.each { |x| add x }
|
44
|
+
x = options.delete(:parts)
|
45
|
+
add x if x
|
46
|
+
add_options options
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.from(*h)
|
50
|
+
FieldSpec.new(*h)
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_s
|
54
|
+
@parts.delete_if { |x|
|
55
|
+
x.nil? or
|
56
|
+
(x.is_a? String and x.empty?) or
|
57
|
+
(x.is_a? FieldSpec and x.to_s.empty?)
|
58
|
+
}
|
59
|
+
result = @parts.join(@join)
|
60
|
+
unless result.empty?
|
61
|
+
result = (@prefix || '').to_s + result + (@postfix || '').to_s
|
62
|
+
end
|
63
|
+
result
|
64
|
+
end
|
65
|
+
|
66
|
+
def add(part)
|
67
|
+
case part
|
68
|
+
when Hash
|
69
|
+
@parts << FieldSpec::from(part)
|
70
|
+
when Array
|
71
|
+
part.each { |x| add x }
|
72
|
+
else
|
73
|
+
@parts << part
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Libis
|
4
|
+
module Tools
|
5
|
+
module Metadata
|
6
|
+
|
7
|
+
class FixField
|
8
|
+
|
9
|
+
attr_reader :tag
|
10
|
+
attr_reader :datas
|
11
|
+
|
12
|
+
def initialize(tag, datas)
|
13
|
+
@tag = tag
|
14
|
+
@datas = datas || ''
|
15
|
+
end
|
16
|
+
|
17
|
+
def dump
|
18
|
+
"#{@tag}:'#{@datas}'\n"
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'cgi'
|
4
|
+
|
5
|
+
require_relative 'marc_record'
|
6
|
+
|
7
|
+
module Libis
|
8
|
+
module Tools
|
9
|
+
module Metadata
|
10
|
+
|
11
|
+
class Marc21Record < Libis::Tools::Metadata::MarcRecord
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def get_all_records
|
16
|
+
|
17
|
+
@all_records = Hash.new { |h, k| h[k] = [] }
|
18
|
+
|
19
|
+
@node.xpath('.//leader').each { |f|
|
20
|
+
@all_records['LDR'] << FixField.new('LDR', f.content)
|
21
|
+
}
|
22
|
+
|
23
|
+
@node.xpath('.//controlfield').each { |f|
|
24
|
+
tag = f['tag']
|
25
|
+
tag = '%03d' % tag.to_i if tag.size < 3
|
26
|
+
@all_records[tag] << FixField.new(tag, CGI::escapeHTML(f.content))
|
27
|
+
}
|
28
|
+
|
29
|
+
@node.xpath('.//datafield').each { |v|
|
30
|
+
|
31
|
+
tag = v['tag']
|
32
|
+
tag = '%03d' % tag.to_i if tag.size < 3
|
33
|
+
|
34
|
+
subfields = Hash.new { |h, k| h[k] = [] }
|
35
|
+
v.xpath('.//subfield').each { |s| subfields[s['code']] << CGI::escapeHTML(s.content) }
|
36
|
+
|
37
|
+
@all_records[tag] << VarField.new(tag, v['ind1'].to_s, v['ind2'].to_s, subfields)
|
38
|
+
|
39
|
+
}
|
40
|
+
|
41
|
+
@all_records
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,209 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
require 'cgi'
|
5
|
+
|
6
|
+
require 'libis/tools/xml_document'
|
7
|
+
require 'libis/tools/assert'
|
8
|
+
|
9
|
+
require_relative 'fix_field'
|
10
|
+
require_relative 'var_field'
|
11
|
+
require_relative 'field_spec'
|
12
|
+
|
13
|
+
module Libis
|
14
|
+
module Tools
|
15
|
+
module Metadata
|
16
|
+
|
17
|
+
# noinspection RubyTooManyMethodsInspection
|
18
|
+
class MarcRecord
|
19
|
+
|
20
|
+
def initialize(xml_node)
|
21
|
+
@node = xml_node
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_raw
|
25
|
+
@node
|
26
|
+
end
|
27
|
+
|
28
|
+
def all
|
29
|
+
# noinspection RubyResolve
|
30
|
+
@all_records ||= get_all_records
|
31
|
+
end
|
32
|
+
|
33
|
+
def each
|
34
|
+
all.each do |k, v|
|
35
|
+
yield k, v
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def all_tags(tag, subfields = '')
|
40
|
+
tag_, ind1, ind2 = tag =~ /^\d{3}/ ? [tag[0..2], tag[3], tag[4]] : [tag, nil, nil]
|
41
|
+
result = get_records(tag_, ind1, ind2, subfields)
|
42
|
+
return result unless block_given?
|
43
|
+
result.map { |record| yield record }
|
44
|
+
result.size > 0
|
45
|
+
end
|
46
|
+
|
47
|
+
def first_tag(t, subfields = '')
|
48
|
+
result = all_tags(t, subfields).first
|
49
|
+
return result unless block_given?
|
50
|
+
return false unless result
|
51
|
+
yield result
|
52
|
+
true
|
53
|
+
end
|
54
|
+
|
55
|
+
def each_tag(t, s = '')
|
56
|
+
all_tags(t, s).each do |record|
|
57
|
+
yield record
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def all_fields(t, s)
|
62
|
+
r = all_tags(t, s).collect { |tag| tag.fields_array(s) }.flatten.compact
|
63
|
+
return r unless block_given?
|
64
|
+
r.map { |field| yield field }
|
65
|
+
r.size > 0
|
66
|
+
end
|
67
|
+
|
68
|
+
def first_field(t, s)
|
69
|
+
result = all_fields(t, s).first
|
70
|
+
return result unless block_given?
|
71
|
+
return false unless result
|
72
|
+
yield result
|
73
|
+
true
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
def each_field(t, s)
|
78
|
+
all_fields(t, s).each do |field|
|
79
|
+
yield field
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def marc_dump
|
84
|
+
all.values.flatten.each_with_object([]) { |record, m| m << record.dump }.join
|
85
|
+
end
|
86
|
+
|
87
|
+
def save(filename)
|
88
|
+
|
89
|
+
doc = ::Libis::Tools::XmlDocument.new
|
90
|
+
doc.root = @node
|
91
|
+
|
92
|
+
return doc unless filename
|
93
|
+
|
94
|
+
doc.save filename, save_with: (::Nokogiri::XML::Node::SaveOptions::NO_EMPTY_TAGS |
|
95
|
+
::Nokogiri::XML::Node::SaveOptions::AS_XML |
|
96
|
+
::Nokogiri::XML::Node::SaveOptions::FORMAT
|
97
|
+
)
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.load(filename)
|
102
|
+
|
103
|
+
doc = ::Libis::Tools::XmlDocument.open(filename)
|
104
|
+
self.new(doc.root)
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.read(io)
|
109
|
+
io = StringIO.new(io) if io.is_a? String
|
110
|
+
doc = ::Libis::Tools::XmlDocument.parse(io)
|
111
|
+
self.new(doc.root)
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
def to_aseq
|
116
|
+
record = ''
|
117
|
+
doc_number = tag('001').datas
|
118
|
+
|
119
|
+
all.select { |t| t.is_a? FixField }.each { |t| record += "#{format('%09s', doc_number)} #{t.tag} L #{t.datas}\n" }
|
120
|
+
all.select { |t| t.is_a? VarField }.each { |t|
|
121
|
+
record += "#{format('%09s', doc_number)} #{t.tag}#{t.ind1}#{t.ind2} L "
|
122
|
+
t.keys.each { |k|
|
123
|
+
t.field_array(k).each { |f|
|
124
|
+
record += "$$#{k}#{CGI::unescapeHTML(f)}"
|
125
|
+
}
|
126
|
+
}
|
127
|
+
record += "\n"
|
128
|
+
}
|
129
|
+
|
130
|
+
record
|
131
|
+
end
|
132
|
+
|
133
|
+
protected
|
134
|
+
|
135
|
+
def element(*parts)
|
136
|
+
opts = options parts
|
137
|
+
field_spec(opts, *parts)
|
138
|
+
end
|
139
|
+
|
140
|
+
def list_s(*parts)
|
141
|
+
opts = options parts, join: ' '
|
142
|
+
field_spec(opts, *parts)
|
143
|
+
end
|
144
|
+
|
145
|
+
def list_c(*parts)
|
146
|
+
opts = options parts, join: ', '
|
147
|
+
field_spec(opts, *parts)
|
148
|
+
end
|
149
|
+
|
150
|
+
def list_d(*parts)
|
151
|
+
opts = options parts, join: ' - '
|
152
|
+
field_spec(opts, *parts)
|
153
|
+
end
|
154
|
+
|
155
|
+
def repeat(*parts)
|
156
|
+
opts = options parts, join: '; '
|
157
|
+
field_spec(opts, *parts)
|
158
|
+
end
|
159
|
+
|
160
|
+
def opt_r(*parts)
|
161
|
+
opts = options parts, fix: '()'
|
162
|
+
field_spec(opts, *parts)
|
163
|
+
end
|
164
|
+
|
165
|
+
def opt_s(*parts)
|
166
|
+
opts = options parts, fix: '[]'
|
167
|
+
field_spec(opts, *parts)
|
168
|
+
end
|
169
|
+
|
170
|
+
def odis_link(group, id, label)
|
171
|
+
"http://www.odis.be/lnk/#{group.downcase[0, 2]}_#{id}\##{label}"
|
172
|
+
end
|
173
|
+
|
174
|
+
private
|
175
|
+
|
176
|
+
def options(args, default = {})
|
177
|
+
default.merge(args.last.is_a?(::Hash) ? args.pop : {})
|
178
|
+
end
|
179
|
+
|
180
|
+
def field_spec(default_options, *parts)
|
181
|
+
FieldSpec.new(*parts).add_default_options(default_options).to_s
|
182
|
+
end
|
183
|
+
|
184
|
+
def get_records(tag, ind1 = '', ind2 = '', subfields = '')
|
185
|
+
|
186
|
+
ind1 ||= ''
|
187
|
+
ind2 ||= ''
|
188
|
+
subfields ||= ''
|
189
|
+
|
190
|
+
ind1.tr!('_', ' ')
|
191
|
+
ind1.tr!('#', '')
|
192
|
+
|
193
|
+
ind2.tr!('_', ' ')
|
194
|
+
ind2.tr!('#', '')
|
195
|
+
|
196
|
+
all[tag].select do |v|
|
197
|
+
v.is_a?(FixField) ||
|
198
|
+
((ind1.empty? or v.ind1 == ind1) &&
|
199
|
+
(ind2.empty? or v.ind2 == ind2) &&
|
200
|
+
v.match_fieldspec?(subfields)
|
201
|
+
)
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,224 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'libis/tools/assert'
|
4
|
+
|
5
|
+
module Libis
|
6
|
+
module Tools
|
7
|
+
module Metadata
|
8
|
+
|
9
|
+
class VarField
|
10
|
+
|
11
|
+
attr_reader :tag
|
12
|
+
attr_reader :ind1
|
13
|
+
attr_reader :ind2
|
14
|
+
attr_reader :subfield
|
15
|
+
|
16
|
+
def initialize(tag, ind1, ind2, subfield = {})
|
17
|
+
@tag = tag
|
18
|
+
@ind1 = ind1 || ' '
|
19
|
+
@ind2 = ind2 || ' '
|
20
|
+
@subfield = subfield || {}
|
21
|
+
end
|
22
|
+
|
23
|
+
# dump the contents
|
24
|
+
#
|
25
|
+
# @return [String] debug output to inspect the contents of the VarField
|
26
|
+
def dump
|
27
|
+
output = "#{@tag}:#{@ind1}:#{@ind2}:\n"
|
28
|
+
@subfield.each { |s, t| output += "\t#{s}:#{t}\n" }
|
29
|
+
output
|
30
|
+
end
|
31
|
+
|
32
|
+
# dump the contents
|
33
|
+
#
|
34
|
+
# @return [String] debug output to inspect the contents of the VarField - Single line version
|
35
|
+
def dump_line
|
36
|
+
output = "#{@tag}:#{@ind1}:#{@ind2}:"
|
37
|
+
@subfield.each { |s, t| output += "$#{s}#{t}" }
|
38
|
+
output
|
39
|
+
end
|
40
|
+
|
41
|
+
# list the subfield codes
|
42
|
+
#
|
43
|
+
# @return [Array] a list of all subfield codes
|
44
|
+
def keys
|
45
|
+
@subfield.keys
|
46
|
+
end
|
47
|
+
|
48
|
+
# get the first (or only) subfield value for the given code
|
49
|
+
#
|
50
|
+
# @return [String] the first or only entry of a subfield or nil if not present
|
51
|
+
# @param s [Character] the subfield code
|
52
|
+
def field(s)
|
53
|
+
field_array(s).first
|
54
|
+
end
|
55
|
+
|
56
|
+
# get a list of all subfield values for a given code
|
57
|
+
#
|
58
|
+
# @return [Array] all the entries of a repeatable subfield
|
59
|
+
# @param s [Character] the subfield code
|
60
|
+
def field_array(s)
|
61
|
+
assert(s.is_a?(String) && (s =~ /^[\da-z]$/) == 0, 'method expects a lower case alphanumerical char')
|
62
|
+
@subfield.has_key?(s) ? @subfield[s].dup : []
|
63
|
+
end
|
64
|
+
|
65
|
+
# get a list of the first subfield value for all the codes in the given string
|
66
|
+
#
|
67
|
+
# @return [Array] list of the first or only entries of all subfield codes in the input string
|
68
|
+
# @param s [String] subfield code specification (see match_fieldspec?)
|
69
|
+
#
|
70
|
+
# The subfield codes are cleaned and sorted first (see fieldspec_to_sorted_array)
|
71
|
+
def fields(s)
|
72
|
+
assert(s.is_a?(String), 'method expects a string')
|
73
|
+
return [] unless (match_array = match_fieldspec?(s))
|
74
|
+
fieldspec_to_array(match_array.join(' ')).collect { |i| send(:field, i) }.flatten.compact
|
75
|
+
end
|
76
|
+
|
77
|
+
# get a list of all the subfield values for all the codes in the given string
|
78
|
+
#
|
79
|
+
# @return [Array] list of the all the entries of all subfield codes in the input string
|
80
|
+
# @param s [String] subfield code specification (see match_fieldspec?)
|
81
|
+
#
|
82
|
+
# The subfield codes are cleaned and sorted first (see fieldspec_to_sorted_array)
|
83
|
+
|
84
|
+
def fields_array(s)
|
85
|
+
assert(s.is_a?(String), 'method expects a string')
|
86
|
+
return [] unless (match_array = match_fieldspec?(s))
|
87
|
+
fieldspec_to_array(match_array.join(' ')).collect { |i| send(:field_array, i) }.flatten.compact
|
88
|
+
end
|
89
|
+
|
90
|
+
# check if the current VarField matches the given field specification.
|
91
|
+
#
|
92
|
+
# @return [String] The matching part(s) of the specification or nil if no match
|
93
|
+
# @param fieldspec [String] field specification: sequence of alternative set of subfield codes that should-shouldn't be present
|
94
|
+
#
|
95
|
+
# The fieldspec consists of groups of characters. At least one of these groups should match for the test to succeed
|
96
|
+
# Within the group sets of codes may be divided by a hyphen (-). The first set of codes must all be present;
|
97
|
+
# the second set of codes must all <b>not</b> be present. Either set may be empty.
|
98
|
+
#
|
99
|
+
# Examples:
|
100
|
+
# 'ab' matches '$a...$b...' => ['ab']
|
101
|
+
# '$a...$b...$c...' => ['ab']
|
102
|
+
# but not '$a...' => nil # ($b missing)
|
103
|
+
# '$b...' => nil # ($a missing)
|
104
|
+
# 'a b' matches '$a...' => ['a']
|
105
|
+
# '$b...' => ['b']
|
106
|
+
# '$a...$b...' => ['a', 'b']
|
107
|
+
# '$a...$b...$c...' => ['a', 'b']
|
108
|
+
# but not '$c...' => nil # ($a or $b must be present)
|
109
|
+
# 'abc-d' matches '$a..,$b...$c...' => ['abc-d']
|
110
|
+
# '$a..,$b...$c...$e...' => ['abc-d']
|
111
|
+
# but not '$a...$b...$e...' => nil # ($c missing)
|
112
|
+
# '$a...$b...$c...$d...' => nil # ($d should not be present)
|
113
|
+
# 'a-b b-a' matches '$a...' => ['a-b']
|
114
|
+
# '$a...$c...' => ['a-b']
|
115
|
+
# '$b...' => ['b-a']
|
116
|
+
# '$b...$c...' => ['b-a']
|
117
|
+
# but not '$a...$b...' => nil
|
118
|
+
# 'a-b c-d' matches '$a...' => ['a-b']
|
119
|
+
# '$a...$c...' => ['a-b', 'c-d']
|
120
|
+
# '$a...$b...$c...' => ['c-d']
|
121
|
+
# '$b...$c...' => ['c-d']
|
122
|
+
# but not '$a...$b...' => nil
|
123
|
+
# '$c...$d...' => nil
|
124
|
+
# '$b...$c...$d...' => nil
|
125
|
+
# '$a...$b...$c...$d...' => nil
|
126
|
+
def match_fieldspec?(fieldspec)
|
127
|
+
return [] if fieldspec.empty?
|
128
|
+
result = fieldspec.split.collect { |fs|
|
129
|
+
fa = fs.split '-'
|
130
|
+
assert(fa.size <= 2, 'more than one "-" is not allowed in a fieldspec')
|
131
|
+
must_match = (fa[0] || '').split ''
|
132
|
+
must_not_match = (fa[1] || '').split ''
|
133
|
+
next unless (must_match == (must_match & keys)) && (must_not_match & keys).empty?
|
134
|
+
fs
|
135
|
+
}.compact
|
136
|
+
return nil if result.empty?
|
137
|
+
result
|
138
|
+
end
|
139
|
+
|
140
|
+
private
|
141
|
+
|
142
|
+
# @return [Array] cleaned up version of the input string
|
143
|
+
# @param fieldspec [String] subfield code specification
|
144
|
+
# cleans the subfield code specification and splits it into an array of characters
|
145
|
+
# Duplicates will be removed from the array and the order will be untouched.
|
146
|
+
def fieldspec_to_array(fieldspec)
|
147
|
+
|
148
|
+
# note that we remove the '-xxx' part as it is only required for matching
|
149
|
+
fieldspec.gsub(/ |-\w*/, '').split('').uniq
|
150
|
+
end
|
151
|
+
|
152
|
+
def sort_helper(x)
|
153
|
+
# make sure that everything below 'A' is higher than 'z'
|
154
|
+
# note that this only works for numbers, but that is fine in our case.
|
155
|
+
x < 'A' ? (x.to_i + 123).chr : x
|
156
|
+
end
|
157
|
+
|
158
|
+
# implementation for methods for retrieving subfield values
|
159
|
+
#
|
160
|
+
# The methods start with a single character: the operation
|
161
|
+
# 'f' for retrieving only the first occurence of the subfield
|
162
|
+
# 'a' for retrieving all the subfield values for each of the given subfields
|
163
|
+
# if omitted, 'f' is assumed
|
164
|
+
#
|
165
|
+
# Then a '_' acts as a subdivider between the operation and the subfield(s). It must always be present, even
|
166
|
+
# if the operation is omitted.
|
167
|
+
#
|
168
|
+
# The last past is a sequence of subfield codes that should be used for selecting the values. The order in which the
|
169
|
+
# subfields are listed is respected in the resulting array of values.
|
170
|
+
#
|
171
|
+
# Examples:
|
172
|
+
#
|
173
|
+
# t = VarField.new('100', '', '',
|
174
|
+
# { 'a' => %w'Name NickName',
|
175
|
+
# 'b' => %w'LastName MaidenName',
|
176
|
+
# 'c' => %w'eMail',
|
177
|
+
# '1' => %w'Age',
|
178
|
+
# '9' => %w'Score'})
|
179
|
+
#
|
180
|
+
# # >> 100##$aName$aNickName$bLastName$bMaidenName$ceMail$1Age$9Score <<
|
181
|
+
#
|
182
|
+
# t._1ab => ['Age', 'Name', 'LastName']
|
183
|
+
# # equivalent to: t.f_1av or t.fields('1ab')
|
184
|
+
#
|
185
|
+
# t.a_9ab => ['Score', 'Name', 'NickName', 'LastName', 'MaidenName']
|
186
|
+
# # equivalent to: t.fields_array('9ab')
|
187
|
+
#
|
188
|
+
# Note that it is not possible to use a fieldspec for the sequence of subfield codes. Spaces and '-' are not allowed
|
189
|
+
# in method calls. If you want this, use the #field(s) and #field(s)_array methods.
|
190
|
+
#
|
191
|
+
def method_missing(name, *args)
|
192
|
+
operation, subfields = name.to_s.split('_')
|
193
|
+
assert(subfields.size > 0, 'need to specify at least one subfield')
|
194
|
+
operation = 'f' if operation.empty?
|
195
|
+
# convert subfield list to fieldspec
|
196
|
+
subfields = subfields.split('').join(' ')
|
197
|
+
case operation
|
198
|
+
when 'f'
|
199
|
+
if subfields.size > 1
|
200
|
+
operation = :fields
|
201
|
+
else
|
202
|
+
operation = :field
|
203
|
+
end
|
204
|
+
when 'a'
|
205
|
+
if subfields.size > 1
|
206
|
+
operation = :fields_array
|
207
|
+
else
|
208
|
+
operation = :field_array
|
209
|
+
end
|
210
|
+
else
|
211
|
+
throw "Unknown method invocation: '#{name}' with: #{args}"
|
212
|
+
end
|
213
|
+
send(operation, subfields)
|
214
|
+
end
|
215
|
+
|
216
|
+
def to_ary
|
217
|
+
nil
|
218
|
+
end
|
219
|
+
|
220
|
+
end
|
221
|
+
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
data/lib/libis/tools/version.rb
CHANGED
@@ -280,13 +280,19 @@ module Libis
|
|
280
280
|
# </jkr:books>
|
281
281
|
# </patron>
|
282
282
|
#
|
283
|
-
# @param [
|
284
|
-
#
|
285
|
-
#
|
286
|
-
#
|
287
|
-
#
|
283
|
+
# @param [Array] args arguments being:
|
284
|
+
# - tag for the new node
|
285
|
+
# - optional content for new node; empty if nil or not present
|
286
|
+
# - optional parent node for new node; root if nil or not present; xml document if root is not defined
|
287
|
+
# - a Hash containing tag-value pairs for each attribute; the special key ':namespaces'
|
288
|
+
# contains a Hash of namespace definitions as in {#add_namespaces}
|
288
289
|
# @return [Nokogiri::XML::Node] the new node
|
289
|
-
def add_node(
|
290
|
+
def add_node(*args)
|
291
|
+
attributes = {}
|
292
|
+
attributes = args.pop if args.last.is_a? Hash
|
293
|
+
name, value, parent = *args
|
294
|
+
|
295
|
+
return nil if name.nil?
|
290
296
|
|
291
297
|
node = Nokogiri::XML::Node.new name.to_s, @document
|
292
298
|
node.content = value
|
@@ -386,7 +392,7 @@ module Libis
|
|
386
392
|
end
|
387
393
|
|
388
394
|
node.namespace_scopes.each do |ns|
|
389
|
-
node.namespace = ns if ns.prefix == node_ns
|
395
|
+
node.namespace = ns if ns.prefix == node_ns.to_s
|
390
396
|
end if node_ns
|
391
397
|
|
392
398
|
node.default_namespace = default_ns if default_ns
|
@@ -430,12 +436,24 @@ module Libis
|
|
430
436
|
# xml_doc.value('//email') # => "harry.potter@hogwarts.edu"
|
431
437
|
#
|
432
438
|
# @param [String] path the name or XPath term to search the node(s)
|
439
|
+
# @param [Node] parent parent node; document if nil
|
433
440
|
# @return [String] content or nil if not found
|
434
|
-
def value(path)
|
435
|
-
|
441
|
+
def value(path, parent = nil)
|
442
|
+
parent ||= document
|
443
|
+
parent.xpath(path).first.content rescue nil
|
436
444
|
end
|
437
445
|
|
438
|
-
|
446
|
+
# Return the content of the first element found.
|
447
|
+
#
|
448
|
+
# Example:
|
449
|
+
#
|
450
|
+
# xml_doc['email'] # => "harry.potter@hogwarts.edu"
|
451
|
+
#
|
452
|
+
# @param [String] path the name or XPath term to search the node(s)
|
453
|
+
# @return [String] content or nil if not found
|
454
|
+
def [](path)
|
455
|
+
xpath(path).first.content rescue nil
|
456
|
+
end
|
439
457
|
|
440
458
|
# Return the content of all elements found.
|
441
459
|
# Example:
|
@@ -548,8 +566,6 @@ module Libis
|
|
548
566
|
node
|
549
567
|
end
|
550
568
|
|
551
|
-
protected
|
552
|
-
|
553
569
|
# Get the first node matching the tag. The node will be seached with XPath search term = "//#{tag}".
|
554
570
|
#
|
555
571
|
# @param [String] tag XML tag to look for; XPath syntax is allowed
|
data/lib/libis/tools.rb
CHANGED
@@ -4,7 +4,9 @@ module Libis
|
|
4
4
|
autoload :Checksum, 'libis/tools/checksum'
|
5
5
|
autoload :Command, 'libis/tools/command'
|
6
6
|
autoload :Config, 'libis/tools/config'
|
7
|
+
autoload :ConfigFile, 'libis/tools/config_file'
|
7
8
|
autoload :DCRecord, 'libis/tools/dc_record'
|
9
|
+
autoload :DeepStruct, 'libis/tools/deep_struct'
|
8
10
|
autoload :Logger, 'libis/tools/logger'
|
9
11
|
autoload :MetsFile, 'libis/tools/mets_file'
|
10
12
|
autoload :Parameter, 'libis/tools/parameter'
|
data/spec/config_file_spec.rb
CHANGED
@@ -30,6 +30,45 @@ describe ::Libis::Tools::ConfigFile do
|
|
30
30
|
expect(subject.to_hash).to eq hash
|
31
31
|
end
|
32
32
|
|
33
|
+
it 'loads a hash' do
|
34
|
+
subject << hash
|
35
|
+
expect(subject.to_hash).to eq hash
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'allows to change sub-hash' do
|
39
|
+
subject << hash
|
40
|
+
# noinspection RubyResolve
|
41
|
+
subject.b.v = 1
|
42
|
+
hash[:b]['v'] = 1
|
43
|
+
expect(subject.to_hash).to eq hash
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'allows to change hash in array' do
|
47
|
+
subject << hash
|
48
|
+
# noinspection RubyResolve
|
49
|
+
subject.c[0][0].a[0].v = 1
|
50
|
+
hash[:c][0][0][:a][0]['v'] = 1
|
51
|
+
expect(subject.to_hash).to eq hash
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'initialization with hash' do
|
57
|
+
subject { ::Libis::Tools::ConfigFile.new hash }
|
58
|
+
|
59
|
+
it 'has hash' do
|
60
|
+
expect(subject.to_hash).to eq hash
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'initialization with file' do
|
66
|
+
subject { ::Libis::Tools::ConfigFile.new test_file }
|
67
|
+
|
68
|
+
it 'has hash' do
|
69
|
+
expect(subject.to_hash).to eq hash
|
70
|
+
end
|
71
|
+
|
33
72
|
end
|
34
73
|
|
35
74
|
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require_relative '../spec_helper'
|
3
|
+
require 'libis/tools/metadata/dublin_core_record'
|
4
|
+
|
5
|
+
require 'rspec/matchers'
|
6
|
+
require 'equivalent-xml'
|
7
|
+
|
8
|
+
describe 'DublinCoreRecord' do
|
9
|
+
|
10
|
+
let(:header) { '<?xml version="1.0" encoding="utf-8"?>' }
|
11
|
+
|
12
|
+
subject(:dc) { Libis::Tools::Metadata::DublinCoreRecord.new(data) {} }
|
13
|
+
|
14
|
+
def dc_xml(tag, value = '', attributes = {})
|
15
|
+
"<dc:#{tag}#{attributes.sort.each{|k,v| " #{k}=\"#{v}\""}.join}>#{value}</dc:#{tag}>"
|
16
|
+
end
|
17
|
+
|
18
|
+
def dcterms_xml(tag, value = '', attributes = {})
|
19
|
+
"<dcterms:#{tag}#{attributes.sort.each{|k,v| " #{k}=\"#{v}\""}.join}>#{value}</dcterms:#{tag}>"
|
20
|
+
end
|
21
|
+
|
22
|
+
def match_xml(doc1, doc2)
|
23
|
+
xml1 = doc1.is_a?(::Libis::Tools::XmlDocument) ? doc1.document : ::Nokogiri::XML(doc1.to_s)
|
24
|
+
xml2 = doc2.is_a?(::Libis::Tools::XmlDocument) ? doc2.document : ::Nokogiri::XML(doc2.to_s)
|
25
|
+
# noinspection RubyResolve
|
26
|
+
expect(xml1).to be_equivalent_to(xml2).respecting_element_order
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'Empty record' do
|
30
|
+
let(:data) { nil }
|
31
|
+
let(:root) { <<STR.chomp
|
32
|
+
<record \
|
33
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" \
|
34
|
+
xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/"
|
35
|
+
STR
|
36
|
+
}
|
37
|
+
let(:record_start) { root + '>' }
|
38
|
+
let(:record_end) { '</record>' }
|
39
|
+
let(:empty_record) { header + root + '/>' }
|
40
|
+
|
41
|
+
|
42
|
+
it 'contains emtpy record' do
|
43
|
+
match_xml dc.document, empty_record
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'add dc:title' do
|
47
|
+
dc.title = 'abc'
|
48
|
+
match_xml dc.document, header + record_start + dc_xml('title', 'abc') + record_end
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'add dc:date' do
|
52
|
+
dc.date = '2001'
|
53
|
+
dc.dcdate = '2002'
|
54
|
+
dc.dc_date = '2003'
|
55
|
+
match_xml dc.document,
|
56
|
+
header +
|
57
|
+
record_start +
|
58
|
+
dc_xml('date', '2001') +
|
59
|
+
dc_xml('date', '2002') +
|
60
|
+
dc_xml('date', '2003') +
|
61
|
+
record_end
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'add dcterms:date' do
|
65
|
+
dc.termsdate = '2001'
|
66
|
+
dc.dctermsdate = '2002'
|
67
|
+
dc.terms_date = '2003'
|
68
|
+
dc.dcterms_date = '2004'
|
69
|
+
match_xml dc.document,
|
70
|
+
header +
|
71
|
+
record_start +
|
72
|
+
dcterms_xml('date', '2001') +
|
73
|
+
dcterms_xml('date', '2002') +
|
74
|
+
dcterms_xml('date', '2003') +
|
75
|
+
dcterms_xml('date', '2004') +
|
76
|
+
record_end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
data/spec/xmldocument_spec.rb
CHANGED
@@ -199,7 +199,7 @@ describe 'XML Document' do
|
|
199
199
|
|
200
200
|
xml_doc.add_node :patron
|
201
201
|
xml_doc.add_node :name, 'Harry Potter'
|
202
|
-
books = xml_doc.add_node :books,
|
202
|
+
books = xml_doc.add_node :books, namespaces: { jkr: 'http://JKRowling.com' , node_ns: 'jkr' }
|
203
203
|
xml_doc.add_node :book, nil, books,
|
204
204
|
title: 'Quidditch Through the Ages', author: 'Kennilworthy Whisp', due_date: '1992-4-23',
|
205
205
|
namespaces: {node_ns: 'jkr'}
|
@@ -362,7 +362,7 @@ describe 'XML Document' do
|
|
362
362
|
|
363
363
|
end
|
364
364
|
|
365
|
-
it '
|
365
|
+
it 'allows to parse xml string, save and reload' do
|
366
366
|
xml_doc = ::Libis::Tools::XmlDocument.parse(<<-END.align_left)
|
367
367
|
<patron>
|
368
368
|
<name>Harry Potter</name>
|
@@ -381,6 +381,10 @@ describe 'XML Document' do
|
|
381
381
|
|
382
382
|
match_xml xml_doc.document, @xml_template
|
383
383
|
|
384
|
+
end
|
385
|
+
|
386
|
+
it 'supports build to create XML document' do
|
387
|
+
|
384
388
|
xml_doc = ::Libis::Tools::XmlDocument.build do
|
385
389
|
# noinspection RubyResolve
|
386
390
|
patron {
|
@@ -394,6 +398,10 @@ describe 'XML Document' do
|
|
394
398
|
|
395
399
|
match_xml xml_doc.document, @xml_template
|
396
400
|
|
401
|
+
end
|
402
|
+
|
403
|
+
it 'supports different ways to create nodes' do
|
404
|
+
|
397
405
|
xml_doc = ::Libis::Tools::XmlDocument.new
|
398
406
|
xml_doc.add_node :patron
|
399
407
|
xml_doc.name = 'Harry Potter'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: libis-tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kris Dekeyser
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-05-
|
11
|
+
date: 2015-05-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -194,10 +194,16 @@ files:
|
|
194
194
|
- lib/libis/tools/extend/string.rb
|
195
195
|
- lib/libis/tools/extend/struct.rb
|
196
196
|
- lib/libis/tools/logger.rb
|
197
|
+
- lib/libis/tools/metadata/dublin_core_record.rb
|
198
|
+
- lib/libis/tools/metadata/field_spec.rb
|
199
|
+
- lib/libis/tools/metadata/fix_field.rb
|
200
|
+
- lib/libis/tools/metadata/marc21_record.rb
|
201
|
+
- lib/libis/tools/metadata/marc_record.rb
|
202
|
+
- lib/libis/tools/metadata/sharepoint_mapping.rb
|
203
|
+
- lib/libis/tools/metadata/sharepoint_record.rb
|
204
|
+
- lib/libis/tools/metadata/var_field.rb
|
197
205
|
- lib/libis/tools/mets_file.rb
|
198
206
|
- lib/libis/tools/parameter.rb
|
199
|
-
- lib/libis/tools/sharepoint_mapping.rb
|
200
|
-
- lib/libis/tools/sharepoint_record.rb
|
201
207
|
- lib/libis/tools/version.rb
|
202
208
|
- lib/libis/tools/xml_document.rb
|
203
209
|
- libis-tools.gemspec
|
@@ -212,6 +218,7 @@ files:
|
|
212
218
|
- spec/data/test_config.yml
|
213
219
|
- spec/deep_struct_spec.rb
|
214
220
|
- spec/logger_spec.rb
|
221
|
+
- spec/metadata/dublin_core_spec.rb
|
215
222
|
- spec/parameter_container_spec.rb
|
216
223
|
- spec/parameter_spec.rb
|
217
224
|
- spec/spec_helper.rb
|
@@ -256,6 +263,7 @@ test_files:
|
|
256
263
|
- spec/data/test_config.yml
|
257
264
|
- spec/deep_struct_spec.rb
|
258
265
|
- spec/logger_spec.rb
|
266
|
+
- spec/metadata/dublin_core_spec.rb
|
259
267
|
- spec/parameter_container_spec.rb
|
260
268
|
- spec/parameter_spec.rb
|
261
269
|
- spec/spec_helper.rb
|