metacrunch-mab2 1.0.1 → 1.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.
- checksums.yaml +4 -4
- data/.gitignore +22 -3
- data/Gemfile +17 -5
- data/Rakefile +1 -0
- data/bin/console +11 -0
- data/bin/setup +7 -0
- data/lib/metacrunch/mab2.rb +3 -7
- data/lib/metacrunch/mab2/builder.rb +52 -0
- data/lib/metacrunch/mab2/document.rb +49 -45
- data/lib/metacrunch/mab2/{aleph_mab_xml_document_factory.rb → document/aleph_mab_xml_parser.rb} +9 -16
- data/lib/metacrunch/mab2/document/controlfield.rb +8 -4
- data/lib/metacrunch/mab2/document/datafield.rb +21 -18
- data/lib/metacrunch/mab2/document/datafield_set.rb +46 -36
- data/lib/metacrunch/mab2/document/subfield.rb +13 -16
- data/lib/metacrunch/mab2/document/subfield_set.rb +39 -36
- data/lib/metacrunch/mab2/version.rb +1 -1
- data/lib/metacrunch/mab2/xml_builder.rb +48 -0
- data/metacrunch-mab2.gemspec +2 -0
- data/spec/{document → metacrunch/mab2/document}/control_field_spec.rb +2 -2
- data/spec/{document → metacrunch/mab2}/document_spec.rb +31 -6
- metadata +44 -11
- data/spec/document/aleph_mab_xml_document_factory_spec.rb +0 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 60d656f23a0579c4c1e0a01c23aec38904fbe529
|
4
|
+
data.tar.gz: 84aeda9371bedc709734eade5d5ae5111d88c76b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 74fabeef356246a5e3eb56961f4a3fabd7b89e915bed639e2f9e08b9bf3676b34c5231a451ad791044f4d21de76e2679b50ccb90e61aab9ad42c4d2c6db4415c
|
7
|
+
data.tar.gz: f263ffe68b46f4c8bf85bf66514b761452b529c924bd675367349825d6eccea8c6b4afda9cd2593c08ae64cef8671964b86e46334710b44778a134bfc9e84095
|
data/.gitignore
CHANGED
@@ -1,5 +1,24 @@
|
|
1
1
|
.DS_Store
|
2
|
-
/Gemfile.lock
|
3
|
-
/.yardoc
|
4
2
|
/doc
|
5
|
-
|
3
|
+
*.gem
|
4
|
+
*.rbc
|
5
|
+
.bundle
|
6
|
+
.config
|
7
|
+
.yardoc
|
8
|
+
Gemfile.lock
|
9
|
+
InstalledFiles
|
10
|
+
_yardoc
|
11
|
+
coverage
|
12
|
+
doc/
|
13
|
+
lib/bundler/man
|
14
|
+
pkg
|
15
|
+
rdoc
|
16
|
+
spec/reports
|
17
|
+
test/tmp
|
18
|
+
test/version_tmp
|
19
|
+
tmp
|
20
|
+
*.bundle
|
21
|
+
*.so
|
22
|
+
*.o
|
23
|
+
*.a
|
24
|
+
mkmf.log
|
data/Gemfile
CHANGED
@@ -4,10 +4,22 @@ gemspec
|
|
4
4
|
|
5
5
|
gem "metacrunch", ">= 2.1.0", github: "ubpb/metacrunch", branch: "master"
|
6
6
|
|
7
|
-
|
8
|
-
gem "
|
9
|
-
gem "
|
10
|
-
gem "
|
7
|
+
group :development do
|
8
|
+
gem "benchmark-ips"
|
9
|
+
gem "bundler"
|
10
|
+
gem "rake"
|
11
|
+
gem "rspec", ">= 3.0.0", "< 4.0.0"
|
12
|
+
gem "simplecov", ">= 0.8.0"
|
13
|
+
|
14
|
+
if !ENV["CI"]
|
15
|
+
gem "hashdiff"
|
16
|
+
gem "pry", "~> 0.9.12.6"
|
17
|
+
gem "pry-byebug", "<= 1.3.2"
|
18
|
+
gem "pry-rescue", "~> 1.4.2"
|
19
|
+
gem "pry-stack_explorer", "~> 0.4.9.1"
|
20
|
+
gem "pry-syntax-hacks", "~> 0.0.6"
|
21
|
+
end
|
22
|
+
end
|
11
23
|
|
12
24
|
# for benchmarking
|
13
|
-
gem "mabmapper", github: "ubpb/mabmapper", branch: "master"
|
25
|
+
# gem "mabmapper", github: "ubpb/mabmapper", branch: "master"
|
data/Rakefile
CHANGED
data/bin/console
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "metacrunch/mab2"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
require "pry"
|
11
|
+
Pry.start
|
data/bin/setup
ADDED
data/lib/metacrunch/mab2.rb
CHANGED
@@ -2,15 +2,11 @@ require "metacrunch"
|
|
2
2
|
require "ox"
|
3
3
|
require "htmlentities"
|
4
4
|
|
5
|
-
begin
|
6
|
-
require "pry"
|
7
|
-
rescue LoadError ; end
|
8
|
-
|
9
5
|
module Metacrunch
|
10
6
|
module Mab2
|
11
|
-
require_relative "./mab2/
|
12
|
-
require_relative "./mab2/document"
|
7
|
+
require_relative "./mab2/builder"
|
13
8
|
require_relative "./mab2/cli"
|
14
|
-
require_relative "./mab2/
|
9
|
+
require_relative "./mab2/document"
|
10
|
+
require_relative "./mab2/version"
|
15
11
|
end
|
16
12
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require_relative "./document"
|
2
|
+
|
3
|
+
module Metacrunch
|
4
|
+
module Mab2
|
5
|
+
class Builder
|
6
|
+
|
7
|
+
attr_reader :document
|
8
|
+
|
9
|
+
def self.build(&block)
|
10
|
+
builder = new
|
11
|
+
document = builder.instance_eval(&block) if block_given?
|
12
|
+
document || Document.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@document = Document.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def controlfield(tag, values)
|
20
|
+
controlfield = Document::Controlfield.new(tag, values)
|
21
|
+
@document.add_controlfield(controlfield)
|
22
|
+
@document
|
23
|
+
end
|
24
|
+
|
25
|
+
def datafield(tag, ind1:nil, ind2:nil, &block)
|
26
|
+
datafield = Document::Datafield.new(tag, ind1: ind1, ind2: ind2)
|
27
|
+
@document.add_datafield(datafield)
|
28
|
+
|
29
|
+
if block_given?
|
30
|
+
subfield_builder = SubfieldBuilder.new(datafield)
|
31
|
+
subfield_builder.instance_eval(&block)
|
32
|
+
end
|
33
|
+
|
34
|
+
@document
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
class SubfieldBuilder
|
39
|
+
def initialize(datafield)
|
40
|
+
@datafield = datafield
|
41
|
+
end
|
42
|
+
|
43
|
+
def subfield(code, value)
|
44
|
+
subfield = Document::Subfield.new(code, value)
|
45
|
+
@datafield.add_subfield(subfield)
|
46
|
+
subfield
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module Metacrunch
|
2
2
|
module Mab2
|
3
3
|
class Document
|
4
|
+
require_relative "./document/aleph_mab_xml_parser"
|
4
5
|
require_relative "./document/controlfield"
|
5
6
|
require_relative "./document/datafield"
|
6
7
|
require_relative "./document/datafield_set"
|
@@ -16,31 +17,26 @@ module Metacrunch
|
|
16
17
|
# @return [Metacrunch::Mab2::Document]
|
17
18
|
#
|
18
19
|
def self.from_aleph_mab_xml(xml)
|
19
|
-
|
20
|
+
AlephMabXmlParser.parse(xml)
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize
|
24
|
+
@controlfields = {}
|
25
|
+
@datafields = {}
|
20
26
|
end
|
21
27
|
|
22
28
|
# ------------------------------------------------------------------------------
|
23
29
|
# Control fields
|
24
30
|
# ------------------------------------------------------------------------------
|
25
31
|
|
26
|
-
#
|
27
|
-
# @return [Hash{String => Metacrunch::Mab2::Document::Controlfield}]
|
28
|
-
# @private
|
29
|
-
#
|
30
|
-
def controlfields_struct
|
31
|
-
@controlfields_struct ||= {}
|
32
|
-
end
|
33
|
-
private :controlfields_struct
|
34
|
-
|
35
32
|
#
|
36
33
|
# Returns the control field matching the given tag.
|
37
34
|
#
|
38
35
|
# @param [String] tag of the control field
|
39
|
-
# @return [Controlfield
|
40
|
-
# if the control field doesn't exists.
|
36
|
+
# @return [Controlfield] control field with the given tag.
|
41
37
|
#
|
42
38
|
def controlfield(tag)
|
43
|
-
|
39
|
+
@controlfields[tag] || Controlfield.new(tag)
|
44
40
|
end
|
45
41
|
|
46
42
|
#
|
@@ -49,44 +45,35 @@ module Metacrunch
|
|
49
45
|
# @param [Metacrunch::Mab2::Document::Controlfield] controlfield
|
50
46
|
#
|
51
47
|
def add_controlfield(controlfield)
|
52
|
-
|
48
|
+
@controlfields[controlfield.tag] = controlfield
|
53
49
|
end
|
54
50
|
|
55
51
|
# ------------------------------------------------------------------------------
|
56
52
|
# Data fields
|
57
53
|
# ------------------------------------------------------------------------------
|
58
54
|
|
59
|
-
#
|
60
|
-
# @return [Hash{String => Metacrunch::Mab2::Document::Datafield::Set}]
|
61
|
-
# @private
|
62
|
-
#
|
63
|
-
def datafields_struct
|
64
|
-
@datafields_struct ||= {}
|
65
|
-
end
|
66
|
-
private :datafields_struct
|
67
|
-
|
68
55
|
#
|
69
56
|
# Returns the data fields matching the given tag and ind1/ind2.
|
70
57
|
#
|
71
|
-
# @param [String] tag of the data field
|
72
|
-
# @param [String, nil] ind1 filter for ind1. Can be nil to match any.
|
73
|
-
# @param [String, nil] ind2 filter for ind2. Can be nil to match any.
|
74
|
-
# @return [Metacrunch::Mab2::Document::
|
58
|
+
# @param [String, nil] tag of the data field. Can be nil to match any data field.
|
59
|
+
# @param [String, nil] ind1 filter for ind1. Can be nil to match any indicator 1.
|
60
|
+
# @param [String, nil] ind2 filter for ind2. Can be nil to match any indicator 2.
|
61
|
+
# @return [Metacrunch::Mab2::Document::DatafieldSet] data field with the given tag and ind1/ind2.
|
75
62
|
# The set is empty if a matching field with the tag and/or ind1/ind2 doesn't exists.
|
76
63
|
#
|
77
|
-
def datafields(tag, ind1: nil, ind2: nil)
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
if ind1 || ind2
|
82
|
-
filtered_datafields = set.select do |datafield|
|
83
|
-
(!ind1 || (ind1 == :blank ? datafield.ind1 == " " || datafield.ind1 == "-" : datafield.ind1 == ind1)) &&
|
84
|
-
(!ind2 || (ind2 == :blank ? datafield.ind2 == " " || datafield.ind2 == "-" : datafield.ind2 == ind2))
|
85
|
-
end
|
86
|
-
|
87
|
-
Datafield::Set.new(filtered_datafields)
|
64
|
+
def datafields(tag = nil, ind1: nil, ind2: nil)
|
65
|
+
if tag.nil?
|
66
|
+
DatafieldSet.new(@datafields.values.flatten(1))
|
88
67
|
else
|
89
|
-
set
|
68
|
+
set = DatafieldSet.new(@datafields[tag] || [])
|
69
|
+
return set if set.empty? || (ind1.nil? && ind2.nil?)
|
70
|
+
|
71
|
+
ind1 = map_indicator(ind1)
|
72
|
+
ind2 = map_indicator(ind2)
|
73
|
+
|
74
|
+
set.select do |_datafield|
|
75
|
+
check_indicator(ind1, _datafield.ind1) && check_indicator(ind2, _datafield.ind2)
|
76
|
+
end
|
90
77
|
end
|
91
78
|
end
|
92
79
|
|
@@ -96,10 +83,7 @@ module Metacrunch
|
|
96
83
|
# @param [Metacrunch::Mab2::Document::Datafield] datafield
|
97
84
|
#
|
98
85
|
def add_datafield(datafield)
|
99
|
-
|
100
|
-
datafield_set << datafield
|
101
|
-
|
102
|
-
datafields_struct[datafield.tag] = datafield_set
|
86
|
+
(@datafields[datafield.tag] ||= []) << datafield
|
103
87
|
end
|
104
88
|
|
105
89
|
# ------------------------------------------------------------------------------
|
@@ -107,19 +91,39 @@ module Metacrunch
|
|
107
91
|
# ------------------------------------------------------------------------------
|
108
92
|
|
109
93
|
def to_xml
|
110
|
-
builder = Builder::XmlMarkup.new(indent: 2)
|
94
|
+
builder = ::Builder::XmlMarkup.new(indent: 2)
|
111
95
|
builder.instruct!(:xml, :encoding => "UTF-8")
|
112
96
|
builder.mab_xml do
|
113
97
|
controlfields_struct.values.each do |_controlfield|
|
114
98
|
_controlfield.to_xml(builder)
|
115
99
|
end
|
116
100
|
|
117
|
-
|
101
|
+
@datafields.values.each do |_datafield_set|
|
118
102
|
_datafield_set.to_xml(builder)
|
119
103
|
end
|
120
104
|
end
|
121
105
|
end
|
122
106
|
|
107
|
+
private
|
108
|
+
|
109
|
+
def map_indicator(ind)
|
110
|
+
ind.is_a?(Array) ? ind.map { |_el| _el == :blank ? [" ", "-", nil] : _el }.flatten(1) : ind
|
111
|
+
end
|
112
|
+
|
113
|
+
def check_indicator(requested_ind, datafield_ind)
|
114
|
+
if !requested_ind
|
115
|
+
true
|
116
|
+
elsif requested_ind == :blank && (datafield_ind == " " || datafield_ind == "-" || datafield_ind.nil?)
|
117
|
+
true
|
118
|
+
elsif requested_ind == datafield_ind
|
119
|
+
true
|
120
|
+
elsif requested_ind.is_a?(Array) && requested_ind.include?(datafield_ind)
|
121
|
+
true
|
122
|
+
else
|
123
|
+
false
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
123
127
|
end
|
124
128
|
end
|
125
129
|
end
|
data/lib/metacrunch/mab2/{aleph_mab_xml_document_factory.rb → document/aleph_mab_xml_parser.rb}
RENAMED
@@ -1,22 +1,15 @@
|
|
1
1
|
require "htmlentities"
|
2
2
|
require "ox"
|
3
|
-
require_relative "
|
3
|
+
require_relative "../document"
|
4
4
|
|
5
5
|
module Metacrunch
|
6
6
|
module Mab2
|
7
|
-
class
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
def to_document
|
14
|
-
@document ||= Parser.new.parse(@aleph_mab_xml)
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
7
|
+
class Document
|
8
|
+
class AlephMabXmlParser < Ox::Sax
|
9
|
+
def self.parse(aleph_mab_xml)
|
10
|
+
new.parse(aleph_mab_xml)
|
11
|
+
end
|
18
12
|
|
19
|
-
class Parser < Ox::Sax
|
20
13
|
def parse(io_or_string)
|
21
14
|
# initialize state machine
|
22
15
|
@in_controlfield = @in_datafield = @in_subfield = false
|
@@ -37,13 +30,13 @@ module Metacrunch
|
|
37
30
|
def start_element(name)
|
38
31
|
if name == :subfield
|
39
32
|
@in_subfield = true
|
40
|
-
@subfield = Document::
|
33
|
+
@subfield = Metacrunch::Mab2::Document::Subfield.new
|
41
34
|
elsif name == :datafield
|
42
35
|
@in_datafield = true
|
43
|
-
@datafield = Document::Datafield.new
|
36
|
+
@datafield = Metacrunch::Mab2::Document::Datafield.new
|
44
37
|
elsif name == :controlfield
|
45
38
|
@in_controlfield = true
|
46
|
-
@controlfield = Document::Controlfield.new
|
39
|
+
@controlfield = Metacrunch::Mab2::Document::Controlfield.new
|
47
40
|
end
|
48
41
|
end
|
49
42
|
|
@@ -60,7 +60,7 @@ module Metacrunch
|
|
60
60
|
# ------------------------------------------------------------------------------
|
61
61
|
|
62
62
|
def to_xml(builder)
|
63
|
-
builder.controlfield(
|
63
|
+
builder.controlfield(values2string, tag: tag)
|
64
64
|
end
|
65
65
|
|
66
66
|
private
|
@@ -69,11 +69,11 @@ module Metacrunch
|
|
69
69
|
string.chars.to_a.map{ |e| (e=="|") ? nil : e }
|
70
70
|
end
|
71
71
|
|
72
|
-
def array2values(
|
73
|
-
|
72
|
+
def array2values(array)
|
73
|
+
array.map do |v|
|
74
74
|
if v.present?
|
75
75
|
v = v.to_s
|
76
|
-
raise ArgumentError, "invalid value of controlfield #{tag}: #{
|
76
|
+
raise ArgumentError, "invalid value of controlfield #{tag}: #{array}" if v.length > 1
|
77
77
|
v
|
78
78
|
else
|
79
79
|
nil
|
@@ -81,6 +81,10 @@ module Metacrunch
|
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
|
+
def values2string
|
85
|
+
values.map{|c| c.blank? ? "|" : c}.join
|
86
|
+
end
|
87
|
+
|
84
88
|
end
|
85
89
|
end
|
86
90
|
end
|
@@ -10,42 +10,45 @@ module Metacrunch
|
|
10
10
|
@tag = tag
|
11
11
|
@ind1 = ind1
|
12
12
|
@ind2 = ind2
|
13
|
+
@subfields = {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def value
|
17
|
+
subfields.value
|
13
18
|
end
|
14
19
|
|
15
20
|
# ------------------------------------------------------------------------------
|
16
21
|
# Sub fields
|
17
22
|
# ------------------------------------------------------------------------------
|
18
23
|
|
19
|
-
#
|
20
|
-
# @return [Hash{String => Metacrunch::Mab2::Document::Datafield::Subfield::Set}]
|
21
|
-
# @private
|
22
|
-
#
|
23
|
-
def subfields_struct
|
24
|
-
@subfields_struct ||= {}
|
25
|
-
end
|
26
|
-
private :subfields_struct
|
27
|
-
|
28
24
|
#
|
29
25
|
# Returns the sub field matching the given code.
|
30
26
|
#
|
31
27
|
# @param [String] code of the sub field
|
32
|
-
# @return [Metacrunch::Mab2::Document::
|
28
|
+
# @return [Metacrunch::Mab2::Document::SubfieldSet] sub field with the given code. The set
|
33
29
|
# is empty if the sub field doesn't exists.
|
34
30
|
#
|
35
|
-
def subfields(code)
|
36
|
-
|
31
|
+
def subfields(code = nil)
|
32
|
+
result = Metacrunch::Mab2::Document::SubfieldSet.new
|
33
|
+
|
34
|
+
if code.nil?
|
35
|
+
result.concat(@subfields.values.flatten(1))
|
36
|
+
elsif _subfields = @subfields[code]
|
37
|
+
result.concat(_subfields)
|
38
|
+
elsif (codes = code).is_a?(Array)
|
39
|
+
result.concat(codes.map { |_code| @subfields[_code] }.compact.flatten(1))
|
40
|
+
end
|
41
|
+
|
42
|
+
result
|
37
43
|
end
|
38
44
|
|
39
45
|
#
|
40
46
|
# Adds a new sub field.
|
41
47
|
#
|
42
|
-
# @param [Metacrunch::Mab2::Document::
|
48
|
+
# @param [Metacrunch::Mab2::Document::Subfield] subfield
|
43
49
|
#
|
44
50
|
def add_subfield(subfield)
|
45
|
-
|
46
|
-
subfield_set << subfield
|
47
|
-
|
48
|
-
subfields_struct[subfield.code] = subfield_set
|
51
|
+
(@subfields[subfield.code] ||= []) << subfield
|
49
52
|
end
|
50
53
|
|
51
54
|
# ------------------------------------------------------------------------------
|
@@ -54,7 +57,7 @@ module Metacrunch
|
|
54
57
|
|
55
58
|
def to_xml(builder)
|
56
59
|
builder.datafield(tag: tag, ind1: ind1, ind2: ind2) do
|
57
|
-
|
60
|
+
@subfields.values.each do |_subfield_set|
|
58
61
|
_subfield_set.to_xml(builder)
|
59
62
|
end
|
60
63
|
end
|
@@ -1,56 +1,66 @@
|
|
1
|
+
require "self_enumerable"
|
2
|
+
|
1
3
|
module Metacrunch
|
2
4
|
module Mab2
|
3
5
|
class Document
|
4
|
-
class
|
5
|
-
|
6
|
-
include Enumerable
|
6
|
+
class DatafieldSet
|
7
|
+
include SelfEnumerable
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
def initialize(datafields = [])
|
10
|
+
@datafields = datafields
|
11
|
+
end
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
def each
|
14
|
+
block_given? ? @datafields.each { |_datafield| yield _datafield } : to_enum
|
15
|
+
end
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
17
|
+
def <<(datafield)
|
18
|
+
@datafields << datafield
|
19
|
+
end
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
21
|
+
def concat(datafield_set)
|
22
|
+
@datafields.concat(datafield_set.to_a)
|
23
|
+
self
|
24
|
+
end
|
23
25
|
|
24
|
-
|
25
|
-
|
26
|
-
|
26
|
+
def value
|
27
|
+
@datafields.find { |_datafield| _datafield.value }.try(:value)
|
28
|
+
end
|
29
|
+
alias_method :first_value, :value
|
27
30
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
+
def to_a
|
32
|
+
@datafields
|
33
|
+
end
|
34
|
+
|
35
|
+
def empty?
|
36
|
+
@datafields.empty?
|
37
|
+
end
|
31
38
|
|
32
|
-
|
33
|
-
|
34
|
-
|
39
|
+
def present?
|
40
|
+
!empty?
|
41
|
+
end
|
35
42
|
|
36
|
-
|
37
|
-
|
38
|
-
|
43
|
+
# @return [Metacrunch::Mab2::Document::SubfieldSet]
|
44
|
+
def subfields(code = nil)
|
45
|
+
result = Metacrunch::Mab2::Document::SubfieldSet.new
|
39
46
|
|
40
|
-
|
47
|
+
@datafields.each do |_datafield|
|
48
|
+
result.concat(_datafield.subfields(code))
|
41
49
|
end
|
42
50
|
|
43
|
-
|
44
|
-
|
45
|
-
# ------------------------------------------------------------------------------
|
51
|
+
result
|
52
|
+
end
|
46
53
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
end
|
51
|
-
end
|
54
|
+
# ------------------------------------------------------------------------------
|
55
|
+
# Serialization
|
56
|
+
# ------------------------------------------------------------------------------
|
52
57
|
|
58
|
+
def to_xml(builder)
|
59
|
+
self.each do |_datafield|
|
60
|
+
_datafield.to_xml(builder)
|
61
|
+
end
|
53
62
|
end
|
63
|
+
|
54
64
|
end
|
55
65
|
end
|
56
66
|
end
|
@@ -1,28 +1,25 @@
|
|
1
1
|
module Metacrunch
|
2
2
|
module Mab2
|
3
3
|
class Document
|
4
|
-
class
|
5
|
-
class Subfield
|
4
|
+
class Subfield
|
6
5
|
|
7
|
-
|
8
|
-
|
6
|
+
attr_accessor :code
|
7
|
+
attr_accessor :value
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
# ------------------------------------------------------------------------------
|
16
|
-
# Serialization
|
17
|
-
# ------------------------------------------------------------------------------
|
9
|
+
def initialize(code = nil, value = nil)
|
10
|
+
@code = code
|
11
|
+
@value = value
|
12
|
+
end
|
18
13
|
|
19
|
-
|
20
|
-
|
21
|
-
|
14
|
+
# ------------------------------------------------------------------------------
|
15
|
+
# Serialization
|
16
|
+
# ------------------------------------------------------------------------------
|
22
17
|
|
18
|
+
def to_xml(builder)
|
19
|
+
builder.subfield(value, code: code)
|
23
20
|
end
|
21
|
+
|
24
22
|
end
|
25
23
|
end
|
26
24
|
end
|
27
25
|
end
|
28
|
-
|
@@ -1,55 +1,58 @@
|
|
1
|
+
require "self_enumerable"
|
2
|
+
|
1
3
|
module Metacrunch
|
2
4
|
module Mab2
|
3
5
|
class Document
|
4
|
-
class
|
5
|
-
|
6
|
-
class Set
|
7
|
-
include Enumerable
|
6
|
+
class SubfieldSet
|
7
|
+
include SelfEnumerable
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
def initialize(subfields = [])
|
10
|
+
@subfields = subfields
|
11
|
+
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
def each
|
14
|
+
block_given? ? @subfields.each { |_subfield| yield _subfield } : to_enum
|
15
|
+
end
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
def <<(subfield)
|
18
|
+
@subfields << subfield
|
19
|
+
end
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
def concat(subfield_set)
|
22
|
+
@subfields.concat(subfield_set.to_a)
|
23
|
+
end
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
def to_a
|
26
|
+
@subfields
|
27
|
+
end
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
def empty?
|
30
|
+
@subfields.empty?
|
31
|
+
end
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
def present?
|
34
|
+
!empty?
|
35
|
+
end
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
def value
|
38
|
+
values.find{ |v| v.present? }
|
39
|
+
end
|
40
|
+
alias_method :first_value, :value
|
40
41
|
|
41
|
-
|
42
|
-
|
43
|
-
|
42
|
+
def values
|
43
|
+
@subfields.map{ |subfield| subfield.value }
|
44
|
+
end
|
44
45
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
end
|
49
|
-
end
|
46
|
+
# ------------------------------------------------------------------------------
|
47
|
+
# Serialization
|
48
|
+
# ------------------------------------------------------------------------------
|
50
49
|
|
50
|
+
def to_xml(builder)
|
51
|
+
self.each do |_subfield|
|
52
|
+
_subfield.to_xml(builder)
|
51
53
|
end
|
52
54
|
end
|
55
|
+
|
53
56
|
end
|
54
57
|
end
|
55
58
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require "nokogiri"
|
2
|
+
require_relative "../mab2"
|
3
|
+
|
4
|
+
class Metacrunch::Mab2::XmlBuilder
|
5
|
+
def initialize(identifier = nil, &block)
|
6
|
+
@builder =
|
7
|
+
Nokogiri::XML::Builder.new do
|
8
|
+
send(
|
9
|
+
:"OAI-PMH",
|
10
|
+
"xmlns" => "http://www.openarchives.org/OAI/2.0/",
|
11
|
+
"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
|
12
|
+
"xsi:schemaLocation" => "http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd"
|
13
|
+
) do
|
14
|
+
ListRecords do
|
15
|
+
record do
|
16
|
+
if identifier
|
17
|
+
header do |_xml|
|
18
|
+
_xml.identifier identifier
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
metadata do
|
23
|
+
record("xmlns" => "http://www.ddb.de/professionell/mabxml/mabxml-1.xsd") do
|
24
|
+
define_singleton_method(:controlfield) do |_tag, _text|
|
25
|
+
send(:method_missing, :controlfield, _text, tag: _tag)
|
26
|
+
end
|
27
|
+
|
28
|
+
define_singleton_method(:datafield) do |_tag, _attributes = {}, &_block|
|
29
|
+
send(:method_missing, :datafield, {tag: _tag}.merge(_attributes), &_block)
|
30
|
+
end
|
31
|
+
|
32
|
+
define_singleton_method(:subfield) do |_code, _text|
|
33
|
+
send(:method_missing, :subfield, _text, code: _code)
|
34
|
+
end
|
35
|
+
|
36
|
+
instance_eval(&block)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_xml
|
46
|
+
@builder.to_xml
|
47
|
+
end
|
48
|
+
end
|
data/metacrunch-mab2.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
describe Metacrunch::Mab2::Document::Controlfield do
|
2
2
|
|
3
|
-
describe "
|
3
|
+
describe "#initialize" do
|
4
4
|
it "creates a new control field when using String values" do
|
5
5
|
field = Metacrunch::Mab2::Document::Controlfield.new("050", "a||b")
|
6
6
|
expect(field.tag).to eq("050")
|
@@ -14,7 +14,7 @@ describe Metacrunch::Mab2::Document::Controlfield do
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
describe "
|
17
|
+
describe "#values=" do
|
18
18
|
let(:field) { Metacrunch::Mab2::Document::Controlfield.new("050", nil) }
|
19
19
|
|
20
20
|
it "sets field values using String" do
|
@@ -1,16 +1,33 @@
|
|
1
1
|
describe Metacrunch::Mab2::Document do
|
2
2
|
|
3
|
-
describe "
|
3
|
+
describe ".from_aleph_mab_xml" do
|
4
4
|
let(:xml) { default_test_xml }
|
5
5
|
let(:document) { Metacrunch::Mab2::Document.from_aleph_mab_xml(xml) }
|
6
|
+
|
6
7
|
subject { document }
|
7
8
|
|
8
|
-
it "should
|
9
|
+
it "should return a Mab2::Document" do
|
9
10
|
expect(subject).to be_instance_of(Metacrunch::Mab2::Document)
|
10
11
|
end
|
12
|
+
|
13
|
+
it "should find 2 data fields with tag 070" do
|
14
|
+
expect(subject.datafields("070").count).to be(2)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should find 1 data field with tag 100" do
|
18
|
+
expect(subject.datafields("100").first).not_to be_nil
|
19
|
+
end
|
20
|
+
|
21
|
+
it "sub field p of data field 100 is not nil" do
|
22
|
+
expect(subject.datafields("100").first.subfields("p").first.value).not_to be_nil
|
23
|
+
end
|
24
|
+
|
25
|
+
it "decodes html entities" do
|
26
|
+
expect(subject.datafields("331").subfields("a").values.first).to eq("<<Das>> Linux für Studenten")
|
27
|
+
end
|
11
28
|
end
|
12
29
|
|
13
|
-
describe "
|
30
|
+
describe "#add_controlfield" do
|
14
31
|
let(:document) { empty_document }
|
15
32
|
|
16
33
|
it "should add control fields" do
|
@@ -19,7 +36,7 @@ describe Metacrunch::Mab2::Document do
|
|
19
36
|
end
|
20
37
|
end
|
21
38
|
|
22
|
-
describe "
|
39
|
+
describe "#controlfield" do
|
23
40
|
let(:document) { default_test_document }
|
24
41
|
subject { document.controlfield("050") }
|
25
42
|
|
@@ -30,7 +47,7 @@ describe Metacrunch::Mab2::Document do
|
|
30
47
|
end
|
31
48
|
end
|
32
49
|
|
33
|
-
describe "
|
50
|
+
describe "#datafields" do
|
34
51
|
let(:document) { default_test_document }
|
35
52
|
|
36
53
|
context "given tag=100" do
|
@@ -72,6 +89,14 @@ describe Metacrunch::Mab2::Document do
|
|
72
89
|
expect(subject.count).to eq(2)
|
73
90
|
end
|
74
91
|
end
|
92
|
+
|
93
|
+
context "given tag=100 and ind1=[:blank, 'a']" do
|
94
|
+
subject { document.datafields("100", ind1: [:blank, "a"]) }
|
95
|
+
|
96
|
+
it "returns only datafield with tag=100 and ind1=(:blank || 'a')" do
|
97
|
+
expect(subject.count).to eq(3)
|
98
|
+
end
|
99
|
+
end
|
75
100
|
end
|
76
101
|
|
77
102
|
private
|
@@ -121,7 +146,7 @@ private
|
|
121
146
|
end
|
122
147
|
|
123
148
|
def create_subfield(code, value)
|
124
|
-
Metacrunch::Mab2::Document::
|
149
|
+
Metacrunch::Mab2::Document::Subfield.new(code, value)
|
125
150
|
end
|
126
151
|
|
127
152
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: metacrunch-mab2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- René Sprotte
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2015-
|
13
|
+
date: 2015-09-25 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: metacrunch
|
@@ -40,6 +40,20 @@ dependencies:
|
|
40
40
|
- - "~>"
|
41
41
|
- !ruby/object:Gem::Version
|
42
42
|
version: '4.3'
|
43
|
+
- !ruby/object:Gem::Dependency
|
44
|
+
name: nokogiri
|
45
|
+
requirement: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '1.6'
|
50
|
+
type: :runtime
|
51
|
+
prerelease: false
|
52
|
+
version_requirements: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - "~>"
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '1.6'
|
43
57
|
- !ruby/object:Gem::Dependency
|
44
58
|
name: ox
|
45
59
|
requirement: !ruby/object:Gem::Requirement
|
@@ -54,9 +68,25 @@ dependencies:
|
|
54
68
|
- - "~>"
|
55
69
|
- !ruby/object:Gem::Version
|
56
70
|
version: '2.1'
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: self_enumerable
|
73
|
+
requirement: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
type: :runtime
|
79
|
+
prerelease: false
|
80
|
+
version_requirements: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
57
85
|
description: MAB2 tools for metacrunch
|
58
86
|
email: r.sprotte@ub.uni-paderborn.de
|
59
|
-
executables:
|
87
|
+
executables:
|
88
|
+
- console
|
89
|
+
- setup
|
60
90
|
extensions: []
|
61
91
|
extra_rdoc_files: []
|
62
92
|
files:
|
@@ -69,22 +99,25 @@ files:
|
|
69
99
|
- Readme.md
|
70
100
|
- benchmarks/mab2_document_parsing.rb
|
71
101
|
- benchmarks/mab2_document_query.rb
|
102
|
+
- bin/console
|
103
|
+
- bin/setup
|
72
104
|
- lib/metacrunch/mab2.rb
|
73
|
-
- lib/metacrunch/mab2/
|
105
|
+
- lib/metacrunch/mab2/builder.rb
|
74
106
|
- lib/metacrunch/mab2/cli.rb
|
75
107
|
- lib/metacrunch/mab2/document.rb
|
108
|
+
- lib/metacrunch/mab2/document/aleph_mab_xml_parser.rb
|
76
109
|
- lib/metacrunch/mab2/document/controlfield.rb
|
77
110
|
- lib/metacrunch/mab2/document/datafield.rb
|
78
111
|
- lib/metacrunch/mab2/document/datafield_set.rb
|
79
112
|
- lib/metacrunch/mab2/document/subfield.rb
|
80
113
|
- lib/metacrunch/mab2/document/subfield_set.rb
|
81
114
|
- lib/metacrunch/mab2/version.rb
|
115
|
+
- lib/metacrunch/mab2/xml_builder.rb
|
82
116
|
- lib/metacrunch_plugin.rb
|
83
117
|
- metacrunch-mab2.gemspec
|
84
118
|
- spec/assets/aleph_mab_xml/file1.xml
|
85
|
-
- spec/document/
|
86
|
-
- spec/
|
87
|
-
- spec/document/document_spec.rb
|
119
|
+
- spec/metacrunch/mab2/document/control_field_spec.rb
|
120
|
+
- spec/metacrunch/mab2/document_spec.rb
|
88
121
|
- spec/spec_helper.rb
|
89
122
|
homepage: http://github.com/ubpb/metacrunch-mab2
|
90
123
|
licenses:
|
@@ -106,13 +139,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
106
139
|
version: '0'
|
107
140
|
requirements: []
|
108
141
|
rubyforge_project:
|
109
|
-
rubygems_version: 2.4.
|
142
|
+
rubygems_version: 2.4.8
|
110
143
|
signing_key:
|
111
144
|
specification_version: 4
|
112
145
|
summary: MAB2 tools for metacrunch
|
113
146
|
test_files:
|
114
147
|
- spec/assets/aleph_mab_xml/file1.xml
|
115
|
-
- spec/document/
|
116
|
-
- spec/
|
117
|
-
- spec/document/document_spec.rb
|
148
|
+
- spec/metacrunch/mab2/document/control_field_spec.rb
|
149
|
+
- spec/metacrunch/mab2/document_spec.rb
|
118
150
|
- spec/spec_helper.rb
|
151
|
+
has_rdoc:
|
@@ -1,37 +0,0 @@
|
|
1
|
-
describe Metacrunch::Mab2::AlephMabXmlDocumentFactory do
|
2
|
-
|
3
|
-
context "with default test xml file" do
|
4
|
-
let(:factory) { Metacrunch::Mab2::AlephMabXmlDocumentFactory.new(default_test_xml) }
|
5
|
-
|
6
|
-
describe ".to_document" do
|
7
|
-
subject { factory.to_document }
|
8
|
-
|
9
|
-
it "should return a Mab2::Document" do
|
10
|
-
expect(subject).to be_instance_of(Metacrunch::Mab2::Document)
|
11
|
-
end
|
12
|
-
|
13
|
-
it "should find 2 data fields with tag 070" do
|
14
|
-
expect(subject.datafields("070").count).to be(2)
|
15
|
-
end
|
16
|
-
|
17
|
-
it "should find 1 data field with tag 100" do
|
18
|
-
expect(subject.datafields("100").first).not_to be_nil
|
19
|
-
end
|
20
|
-
|
21
|
-
it "sub field p of data field 100 is not nil" do
|
22
|
-
expect(subject.datafields("100").first.subfields("p").first.value).not_to be_nil
|
23
|
-
end
|
24
|
-
|
25
|
-
it "decodes html entities" do
|
26
|
-
expect(subject.datafields("331").subfields("a").values.first).to eq("<<Das>> Linux für Studenten")
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
def default_test_xml
|
34
|
-
File.read(File.join(RSpec.root, "assets", "aleph_mab_xml", "file1.xml"))
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|