xml_dsl 0.3.1 → 0.3.2
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/README.md +28 -0
- data/lib/xml_dsl/block_method.rb +25 -12
- data/lib/xml_dsl/extensions.rb +5 -0
- data/lib/xml_dsl/version.rb +1 -1
- data/lib/xml_dsl/xml_parser.rb +13 -0
- data/spec/fixtures/some.xml +2 -0
- data/spec/integrational/example_parser_spec.rb +32 -1
- data/spec/unit/xml_dsl_spec.rb +4 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a06859b2ea2ebab29cd30ca0dd451005459ed911
|
4
|
+
data.tar.gz: 476df9143b24ecc659d2751d06d4b315216394c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8803eeda3e875094fb8a52fed5bf224b5fd0b9f3eebf94f7c6f9632fa8d5be086871bc3e14a05872c0d19795ca6c804662cc98fde2f79fd75554c3db86384343
|
7
|
+
data.tar.gz: 20d55686eebf557caefd68da858ffd8215c1105ae8d53d9231d0d48309402a6cdb469313d58010f047b13d6667a7c28802ab485844b33f26c228a66316667950
|
data/README.md
CHANGED
@@ -70,6 +70,16 @@ Then we can define our mapper as following
|
|
70
70
|
# any length of root path can be provided
|
71
71
|
define_xml_parser Hash, :root, :offer do
|
72
72
|
|
73
|
+
# Here is basic validation blocks
|
74
|
+
# They MUST return some bool (if block)
|
75
|
+
before_parse? do |node|
|
76
|
+
!node.search('magick').empty?
|
77
|
+
end
|
78
|
+
|
79
|
+
# Or just check for must_have key (or path to it)
|
80
|
+
before_parse? :jim
|
81
|
+
before_parse? [:areas, 'area[type=hobby]']
|
82
|
+
|
73
83
|
# We can define a block to call every time an XmlDsl::ParseError os raised
|
74
84
|
# it is raised if null: true is passed to field declaration, or manually via raise XmlDsl::ParseError
|
75
85
|
error_handle do |e, node|
|
@@ -100,10 +110,28 @@ Then we can define our mapper as following
|
|
100
110
|
0
|
101
111
|
end
|
102
112
|
end
|
113
|
+
|
114
|
+
# If something goes wrong - just raise XmlDsl::ParseError manually
|
115
|
+
field :fuu do |_, node|
|
116
|
+
raise XmlDsl::ParseError, 'FUUU' if node.search(:areas).length > 5
|
117
|
+
end
|
103
118
|
end
|
104
119
|
end
|
105
120
|
```
|
106
121
|
|
122
|
+
Then you can use your newly defined parser as you wish:
|
123
|
+
```
|
124
|
+
parser = Parser.new(nifty_xml, some_logger_eg)
|
125
|
+
|
126
|
+
# just iterate with block
|
127
|
+
parser.iterate do |instance|
|
128
|
+
do_stuff_with_newly_mapped_instance_whatever(instance)
|
129
|
+
end
|
130
|
+
|
131
|
+
# or you can pass some accumulator for your instances to be put into
|
132
|
+
parser.iterate acc: []
|
133
|
+
```
|
134
|
+
|
107
135
|
## Contributing
|
108
136
|
|
109
137
|
Feel free to request for some features or fork - implement - pul request.
|
data/lib/xml_dsl/block_method.rb
CHANGED
@@ -7,11 +7,11 @@ module XmlDsl
|
|
7
7
|
@block = block if block_given?
|
8
8
|
end
|
9
9
|
|
10
|
-
def call(
|
10
|
+
def call(a, b = nil, c = nil)
|
11
11
|
if block
|
12
|
-
self.send method, *[
|
12
|
+
self.send method, *[a, b, c].compact + args, &block
|
13
13
|
else
|
14
|
-
self.send method, *[
|
14
|
+
self.send method, *[a, b, c].compact + args
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
@@ -21,15 +21,7 @@ module XmlDsl
|
|
21
21
|
instance[target] = parser.instance_exec instance, node, &block
|
22
22
|
else
|
23
23
|
raise ArgumentError, 'No source specified' if source.nil?
|
24
|
-
|
25
|
-
when [Symbol]
|
26
|
-
source.to_s
|
27
|
-
when [Array]
|
28
|
-
source.join('/')
|
29
|
-
else
|
30
|
-
source.to_s
|
31
|
-
end
|
32
|
-
instance[target] = node.search(source).send(getter).send(matcher)
|
24
|
+
instance[target] = node.search(convert_source(source)).send(getter).send(matcher)
|
33
25
|
end
|
34
26
|
if null
|
35
27
|
raise XmlDsl::ParseError, "#{target} is empty. Node: #{node}" if instance[target].nil? || instance[target] == ""
|
@@ -39,5 +31,26 @@ module XmlDsl
|
|
39
31
|
def error_handle(exception, node, parser, &block)
|
40
32
|
parser.instance_exec exception, node, &block
|
41
33
|
end
|
34
|
+
|
35
|
+
def before_parse?(node, parser, key = nil, &block)
|
36
|
+
if block_given?
|
37
|
+
parser.instance_exec node, &block
|
38
|
+
else
|
39
|
+
raise ArgumentError, 'Key to check is nil' if key.nil?
|
40
|
+
!node.search(convert_source(key)).empty?
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
def convert_source(source)
|
46
|
+
case [source.class]
|
47
|
+
when [Symbol]
|
48
|
+
source.to_s
|
49
|
+
when [Array]
|
50
|
+
source.join('/')
|
51
|
+
else
|
52
|
+
source.to_s
|
53
|
+
end
|
54
|
+
end
|
42
55
|
end
|
43
56
|
end
|
data/lib/xml_dsl/extensions.rb
CHANGED
@@ -23,6 +23,11 @@ module XmlDsl
|
|
23
23
|
raise ArgumentError, "If there is no @xml in parser, pass it to iterate" if xml_obj.nil?
|
24
24
|
xml_obj.search(_xml_root_path).each do |node|
|
25
25
|
begin
|
26
|
+
valid = _xml_parse_callbacks[:before_parsers].map do |bm|
|
27
|
+
bm.call node, self
|
28
|
+
end.reduce(true, :&)
|
29
|
+
next unless valid
|
30
|
+
# mapping
|
26
31
|
instance = _xml_target_class.new
|
27
32
|
_xml_parse_callbacks[:readers].each do |bm|
|
28
33
|
bm.call instance, node, self
|
data/lib/xml_dsl/version.rb
CHANGED
data/lib/xml_dsl/xml_parser.rb
CHANGED
@@ -28,14 +28,27 @@ module XmlDsl
|
|
28
28
|
@owner.instance_variable_set :@xml_parser, self
|
29
29
|
end
|
30
30
|
|
31
|
+
# Field for parse definition
|
32
|
+
# receives args: target, source = nil, getter: :text, matcher: :to_s, null: false
|
33
|
+
# or block with |instance, node|
|
31
34
|
def field(*args, &block)
|
32
35
|
callbacks[:readers] << XmlDsl::BlockMethod.new(:field, *args, &block)
|
33
36
|
end
|
34
37
|
|
38
|
+
# Error handler for automatic or manually raised XmlDsl::ParseError exceptions
|
39
|
+
# receives block with two args error and node, that caused the error to occur
|
40
|
+
# block with |exception, node|
|
35
41
|
def error_handle(*args, &block)
|
36
42
|
callbacks[:error_handlers] << XmlDsl::BlockMethod.new(:error_handle, *args, &block)
|
37
43
|
end
|
38
44
|
|
45
|
+
# Validation like block
|
46
|
+
# receives key: symbol, string, or array of similar
|
47
|
+
# returns bool if true - normal, false - skip this node
|
48
|
+
def before_parse?(*args, &block)
|
49
|
+
callbacks[:before_parsers] << XmlDsl::BlockMethod.new(:before_parse?, *args, &block)
|
50
|
+
end
|
51
|
+
|
39
52
|
def setup_parser_instance(instance)
|
40
53
|
state_lock.synchronize do
|
41
54
|
instance.instance_variable_set :@_xml_root_path, root_path
|
data/spec/fixtures/some.xml
CHANGED
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
require 'support/xml'
|
3
3
|
|
4
4
|
describe 'Example Xml Mapper Spec' do
|
5
|
-
context '
|
5
|
+
context 'basic parser' do
|
6
6
|
before(:each) do
|
7
7
|
clazz = Class.new
|
8
8
|
clazz.class_eval do
|
@@ -100,6 +100,37 @@ describe 'Example Xml Mapper Spec' do
|
|
100
100
|
expect(@external_obj).to receive(:notify).with(kind_of(Nokogiri::XML::Element)).once
|
101
101
|
@parser.iterate
|
102
102
|
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context 'Parser with before_parse validation (good)' do
|
106
|
+
before(:each) do
|
107
|
+
clazz = Class.new
|
108
|
+
@external_obj = double
|
109
|
+
clazz.class_eval do
|
110
|
+
attr_accessor :xml, :external
|
111
|
+
def initialize(xml, external)
|
112
|
+
self.xml = xml
|
113
|
+
self.external = external
|
114
|
+
end
|
115
|
+
|
116
|
+
define_xml_parser Hash, :root, :offer do
|
117
|
+
|
118
|
+
before_parse? do |node|
|
119
|
+
!node.search('magick').empty?
|
120
|
+
end
|
121
|
+
|
122
|
+
before_parse? :jim
|
123
|
+
before_parse? [:areas, 'area[type=hobby]']
|
124
|
+
|
125
|
+
field :id, :id, matcher: :to_i
|
126
|
+
field :minutes, :distance, matcher: :to_i
|
127
|
+
end
|
128
|
+
end
|
129
|
+
@parser = clazz.new some_xml, @external_obj
|
130
|
+
end
|
103
131
|
|
132
|
+
it 'returns only one object' do
|
133
|
+
expect(@parser.iterate(acc:[]).length).to eql(1)
|
134
|
+
end
|
104
135
|
end
|
105
136
|
end
|
data/spec/unit/xml_dsl_spec.rb
CHANGED
@@ -52,6 +52,10 @@ describe XmlDsl do
|
|
52
52
|
expect { in_definition { error_handle } }.to change(xml_parser.callbacks[:error_handlers], :length).by(1)
|
53
53
|
end
|
54
54
|
|
55
|
+
it 'defining before_parse is put inside before_parsers' do
|
56
|
+
expect { in_definition { before_parse? {} } }.to change(xml_parser.callbacks[:before_parsers], :length).by(1)
|
57
|
+
end
|
58
|
+
|
55
59
|
def in_definition(&block)
|
56
60
|
xml_parser.instance_eval &block
|
57
61
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xml_dsl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vladislav Bogomolov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-11-
|
11
|
+
date: 2014-11-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|