hrr_rb_netconf 0.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 +7 -0
- data/.gitignore +28 -0
- data/.rspec +3 -0
- data/.travis.yml +32 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/LICENSE +201 -0
- data/README.md +220 -0
- data/Rakefile +6 -0
- data/demo/server.rb +54 -0
- data/demo/server_over_ssh.rb +97 -0
- data/demo/server_with_session-oriented-database.rb +134 -0
- data/demo/server_with_sessionless-database.rb +81 -0
- data/hrr_rb_netconf.gemspec +28 -0
- data/lib/hrr_rb_netconf.rb +10 -0
- data/lib/hrr_rb_netconf/logger.rb +56 -0
- data/lib/hrr_rb_netconf/server.rb +109 -0
- data/lib/hrr_rb_netconf/server/capabilities.rb +75 -0
- data/lib/hrr_rb_netconf/server/capability.rb +206 -0
- data/lib/hrr_rb_netconf/server/capability/base_1_0.rb +183 -0
- data/lib/hrr_rb_netconf/server/capability/base_1_1.rb +247 -0
- data/lib/hrr_rb_netconf/server/capability/candidate_1_0.rb +34 -0
- data/lib/hrr_rb_netconf/server/capability/confirmed_commit_1_0.rb +24 -0
- data/lib/hrr_rb_netconf/server/capability/confirmed_commit_1_1.rb +24 -0
- data/lib/hrr_rb_netconf/server/capability/rollback_on_error_1_0.rb +16 -0
- data/lib/hrr_rb_netconf/server/capability/startup_1_0.rb +22 -0
- data/lib/hrr_rb_netconf/server/capability/url_1_0.rb +23 -0
- data/lib/hrr_rb_netconf/server/capability/validate_1_0.rb +25 -0
- data/lib/hrr_rb_netconf/server/capability/validate_1_1.rb +25 -0
- data/lib/hrr_rb_netconf/server/capability/writable_running_1_0.rb +17 -0
- data/lib/hrr_rb_netconf/server/capability/xpath_1_0.rb +14 -0
- data/lib/hrr_rb_netconf/server/datastore.rb +30 -0
- data/lib/hrr_rb_netconf/server/datastore/oper_handler.rb +29 -0
- data/lib/hrr_rb_netconf/server/datastore/session.rb +52 -0
- data/lib/hrr_rb_netconf/server/error.rb +52 -0
- data/lib/hrr_rb_netconf/server/error/access_denied.rb +19 -0
- data/lib/hrr_rb_netconf/server/error/bad_attribute.rb +20 -0
- data/lib/hrr_rb_netconf/server/error/bad_element.rb +20 -0
- data/lib/hrr_rb_netconf/server/error/data_exists.rb +19 -0
- data/lib/hrr_rb_netconf/server/error/data_missing.rb +19 -0
- data/lib/hrr_rb_netconf/server/error/in_use.rb +19 -0
- data/lib/hrr_rb_netconf/server/error/invalid_value.rb +19 -0
- data/lib/hrr_rb_netconf/server/error/lock_denied.rb +19 -0
- data/lib/hrr_rb_netconf/server/error/malformed_message.rb +19 -0
- data/lib/hrr_rb_netconf/server/error/missing_attribute.rb +19 -0
- data/lib/hrr_rb_netconf/server/error/missing_element.rb +19 -0
- data/lib/hrr_rb_netconf/server/error/operation_failed.rb +19 -0
- data/lib/hrr_rb_netconf/server/error/operation_not_supported.rb +19 -0
- data/lib/hrr_rb_netconf/server/error/partial_operation.rb +19 -0
- data/lib/hrr_rb_netconf/server/error/resource_denied.rb +19 -0
- data/lib/hrr_rb_netconf/server/error/rollback_failed.rb +19 -0
- data/lib/hrr_rb_netconf/server/error/rpc_errorable.rb +138 -0
- data/lib/hrr_rb_netconf/server/error/too_big.rb +19 -0
- data/lib/hrr_rb_netconf/server/error/unknown_attribute.rb +19 -0
- data/lib/hrr_rb_netconf/server/error/unknown_element.rb +19 -0
- data/lib/hrr_rb_netconf/server/error/unknown_namespace.rb +19 -0
- data/lib/hrr_rb_netconf/server/errors.rb +28 -0
- data/lib/hrr_rb_netconf/server/filter.rb +48 -0
- data/lib/hrr_rb_netconf/server/filter/subtree.rb +135 -0
- data/lib/hrr_rb_netconf/server/filter/xpath.rb +59 -0
- data/lib/hrr_rb_netconf/server/model.rb +123 -0
- data/lib/hrr_rb_netconf/server/model/node.rb +19 -0
- data/lib/hrr_rb_netconf/server/operation.rb +92 -0
- data/lib/hrr_rb_netconf/server/session.rb +177 -0
- data/lib/hrr_rb_netconf/version.rb +6 -0
- metadata +149 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# vim: et ts=2 sw=2
|
3
|
+
|
4
|
+
require 'hrr_rb_netconf/server/error/rpc_errorable'
|
5
|
+
|
6
|
+
module HrrRbNetconf
|
7
|
+
class Server
|
8
|
+
class Error
|
9
|
+
class OperationNotSupported < Error
|
10
|
+
include RpcErrorable
|
11
|
+
|
12
|
+
TAG = 'operation-not-supported'
|
13
|
+
TYPE = ['protocol', 'application']
|
14
|
+
SEVERITY = ['error']
|
15
|
+
INFO = []
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# vim: et ts=2 sw=2
|
3
|
+
|
4
|
+
require 'hrr_rb_netconf/server/error/rpc_errorable'
|
5
|
+
|
6
|
+
module HrrRbNetconf
|
7
|
+
class Server
|
8
|
+
class Error
|
9
|
+
class PartialOperation < Error
|
10
|
+
include RpcErrorable
|
11
|
+
|
12
|
+
TAG = 'partial-operation'
|
13
|
+
TYPE = ['application']
|
14
|
+
SEVERITY = ['error']
|
15
|
+
INFO = ['ok-element', 'err-element', 'noop-element']
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# vim: et ts=2 sw=2
|
3
|
+
|
4
|
+
require 'hrr_rb_netconf/server/error/rpc_errorable'
|
5
|
+
|
6
|
+
module HrrRbNetconf
|
7
|
+
class Server
|
8
|
+
class Error
|
9
|
+
class ResourceDenied < Error
|
10
|
+
include RpcErrorable
|
11
|
+
|
12
|
+
TAG = 'resource-denied'
|
13
|
+
TYPE = ['transport', 'rpc', 'protocol', 'application']
|
14
|
+
SEVERITY = ['error']
|
15
|
+
INFO = []
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# vim: et ts=2 sw=2
|
3
|
+
|
4
|
+
require 'hrr_rb_netconf/server/error/rpc_errorable'
|
5
|
+
|
6
|
+
module HrrRbNetconf
|
7
|
+
class Server
|
8
|
+
class Error
|
9
|
+
class RollbackFailed < Error
|
10
|
+
include RpcErrorable
|
11
|
+
|
12
|
+
TAG = 'rollback-failed'
|
13
|
+
TYPE = ['protocol', 'application']
|
14
|
+
SEVERITY = ['error']
|
15
|
+
INFO = []
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# vim: et ts=2 sw=2
|
3
|
+
|
4
|
+
require 'rexml/document'
|
5
|
+
|
6
|
+
module HrrRbNetconf
|
7
|
+
class Server
|
8
|
+
class Error < StandardError
|
9
|
+
module RpcErrorable
|
10
|
+
def initialize type, severity, info: nil, app_tag: nil, path: nil, message: nil
|
11
|
+
@logger = Logger.new self.class.name
|
12
|
+
|
13
|
+
@tag = self.class::TAG
|
14
|
+
@type = type
|
15
|
+
@severity = severity
|
16
|
+
@info = info
|
17
|
+
@app_tag = app_tag
|
18
|
+
@path = path
|
19
|
+
@message = message
|
20
|
+
|
21
|
+
validate
|
22
|
+
end
|
23
|
+
|
24
|
+
def validate
|
25
|
+
validate_type
|
26
|
+
validate_severity
|
27
|
+
validate_info
|
28
|
+
validate_app_tag
|
29
|
+
validate_path
|
30
|
+
validate_message
|
31
|
+
end
|
32
|
+
|
33
|
+
def validate_type
|
34
|
+
unless self.class::TYPE.include? @type
|
35
|
+
raise ArgumentError.new "error-type arg must be one of #{self.class::TYPE}, but given #{@type}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def validate_severity
|
40
|
+
unless self.class::SEVERITY.include? @severity
|
41
|
+
raise ArgumentError.new "error-severity arg must be one of #{self.class::SEVERITY}, but given #{@severity}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def validate_info
|
46
|
+
unless self.class::INFO.empty?
|
47
|
+
unless @info.kind_of? Hash
|
48
|
+
raise ArgumentError.new "error-info arg must be a kind of Hash, but given #{@info.class}"
|
49
|
+
end
|
50
|
+
unless self.class::INFO.all?{ |e| @info[e] }
|
51
|
+
raise ArgumentError.new "error-info arg must contain #{self.class::INFO} as keys, but given #{@info}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def validate_app_tag
|
57
|
+
# Pass
|
58
|
+
end
|
59
|
+
|
60
|
+
def validate_path
|
61
|
+
if @path
|
62
|
+
case @path
|
63
|
+
when Hash
|
64
|
+
unless @path['value']
|
65
|
+
raise ArgumentError.new "error-path arg must contain 'value' key if Hash"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def validate_message
|
72
|
+
if @message
|
73
|
+
case @message
|
74
|
+
when Hash
|
75
|
+
unless @message['value']
|
76
|
+
raise ArgumentError.new "error-message arg must contain \"value\" key if Hash"
|
77
|
+
end
|
78
|
+
unless @message.fetch('attributes', {}).keys.include?('xml:lang')
|
79
|
+
@logger.warn { "error-message arg does not contain \"xml:lang\" attribute, so assuming \"en\"" }
|
80
|
+
end
|
81
|
+
else
|
82
|
+
@logger.warn { "error-message arg does not contain \"xml:lang\" attribute, so assuming \"en\"" }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def to_rpc_error
|
88
|
+
xml_doc = REXML::Document.new
|
89
|
+
rpc_error_e = xml_doc.add_element 'rpc-error'
|
90
|
+
tag_e = rpc_error_e.add_element 'error-tag'
|
91
|
+
tag_e.text = @tag
|
92
|
+
type_e = rpc_error_e.add_element 'error-type'
|
93
|
+
type_e.text = @type
|
94
|
+
severity_e = rpc_error_e.add_element 'error-severity'
|
95
|
+
severity_e.text = @severity
|
96
|
+
if @info
|
97
|
+
info_e = rpc_error_e.add_element 'error-info'
|
98
|
+
case @info
|
99
|
+
when Hash
|
100
|
+
@info.each{ |k, v|
|
101
|
+
child_e = info_e.add_element k
|
102
|
+
child_e.text = v
|
103
|
+
}
|
104
|
+
else
|
105
|
+
info_e.text = @info
|
106
|
+
end
|
107
|
+
end
|
108
|
+
if @app_tag
|
109
|
+
app_tag_e = rpc_error_e.add_element 'error-app-tag'
|
110
|
+
app_tag_e.text = @app_tag
|
111
|
+
end
|
112
|
+
if @path
|
113
|
+
path_e = rpc_error_e.add_element 'error-path'
|
114
|
+
case @path
|
115
|
+
when Hash
|
116
|
+
path_e.add_attributes @path['attributes']
|
117
|
+
path_e.text = @path['value']
|
118
|
+
else
|
119
|
+
path_e.text = @path
|
120
|
+
end
|
121
|
+
end
|
122
|
+
if @message
|
123
|
+
message_e = rpc_error_e.add_element 'error-message'
|
124
|
+
message_e.add_attribute 'xml:lang', 'en'
|
125
|
+
case @message
|
126
|
+
when Hash
|
127
|
+
message_e.add_attributes @message['attributes']
|
128
|
+
message_e.text = @message['value']
|
129
|
+
else
|
130
|
+
message_e.text = @message
|
131
|
+
end
|
132
|
+
end
|
133
|
+
xml_doc.root
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# vim: et ts=2 sw=2
|
3
|
+
|
4
|
+
require 'hrr_rb_netconf/server/error/rpc_errorable'
|
5
|
+
|
6
|
+
module HrrRbNetconf
|
7
|
+
class Server
|
8
|
+
class Error
|
9
|
+
class TooBig < Error
|
10
|
+
include RpcErrorable
|
11
|
+
|
12
|
+
TAG = 'too-big'
|
13
|
+
TYPE = ['transport', 'rpc', 'protocol', 'application']
|
14
|
+
SEVERITY = ['error']
|
15
|
+
INFO = []
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# vim: et ts=2 sw=2
|
3
|
+
|
4
|
+
require 'hrr_rb_netconf/server/error/rpc_errorable'
|
5
|
+
|
6
|
+
module HrrRbNetconf
|
7
|
+
class Server
|
8
|
+
class Error
|
9
|
+
class UnknownAttribute < Error
|
10
|
+
include RpcErrorable
|
11
|
+
|
12
|
+
TAG = 'unknown-attribute'
|
13
|
+
TYPE = ['rpc', 'protocol', 'application']
|
14
|
+
SEVERITY = ['error']
|
15
|
+
INFO = ['bad-attribute', 'bad-element']
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# vim: et ts=2 sw=2
|
3
|
+
|
4
|
+
require 'hrr_rb_netconf/server/error/rpc_errorable'
|
5
|
+
|
6
|
+
module HrrRbNetconf
|
7
|
+
class Server
|
8
|
+
class Error
|
9
|
+
class UnknownElement < Error
|
10
|
+
include RpcErrorable
|
11
|
+
|
12
|
+
TAG = 'unknown-element'
|
13
|
+
TYPE = ['protocol', 'application']
|
14
|
+
SEVERITY = ['error']
|
15
|
+
INFO = ['bad-element']
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# vim: et ts=2 sw=2
|
3
|
+
|
4
|
+
require 'hrr_rb_netconf/server/error/rpc_errorable'
|
5
|
+
|
6
|
+
module HrrRbNetconf
|
7
|
+
class Server
|
8
|
+
class Error
|
9
|
+
class UnknownNamespace < Error
|
10
|
+
include RpcErrorable
|
11
|
+
|
12
|
+
TAG = 'unknown-namespace'
|
13
|
+
TYPE = ['protocol', 'application']
|
14
|
+
SEVERITY = ['error']
|
15
|
+
INFO = ['bad-element', 'bad-namespace']
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# vim: et ts=2 sw=2
|
3
|
+
|
4
|
+
require 'hrr_rb_netconf/server/error'
|
5
|
+
|
6
|
+
module HrrRbNetconf
|
7
|
+
class Server
|
8
|
+
class Errors < StandardError
|
9
|
+
include Enumerable
|
10
|
+
|
11
|
+
def initialize *errors
|
12
|
+
@errors = errors.flatten
|
13
|
+
validate_errors
|
14
|
+
end
|
15
|
+
|
16
|
+
def validate_errors
|
17
|
+
unless @errors.all?{ |e| e.kind_of? HrrRbNetconf::Server::Error }
|
18
|
+
given = @errors.reject{ |e| e.kind_of? HrrRbNetconf::Server::Error }.map{ |e| e.class }
|
19
|
+
raise ArgumentError.new "Wrong argument type: given #{given}, expected HrrRbNetconf::Server::Error"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def each &blk
|
24
|
+
@errors.each &blk
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# vim: et ts=2 sw=2
|
3
|
+
|
4
|
+
module HrrRbNetconf
|
5
|
+
class Server
|
6
|
+
class Filter
|
7
|
+
@subclass_list = Array.new
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def inherited klass
|
11
|
+
@subclass_list.push klass if @subclass_list
|
12
|
+
end
|
13
|
+
|
14
|
+
def [] key
|
15
|
+
__subclass_list__(__method__).find{ |klass| klass::TYPE == key }
|
16
|
+
end
|
17
|
+
|
18
|
+
def list
|
19
|
+
__subclass_list__(__method__).map{ |klass| klass::TYPE }
|
20
|
+
end
|
21
|
+
|
22
|
+
def __subclass_list__ method_name
|
23
|
+
send(:method_missing, method_name) unless @subclass_list
|
24
|
+
@subclass_list
|
25
|
+
end
|
26
|
+
|
27
|
+
def filter raw_output_e, input_e
|
28
|
+
filter_e = input_e.elements['filter']
|
29
|
+
if filter_e
|
30
|
+
filter_type = filter_e.attributes['type']
|
31
|
+
if self[filter_type]
|
32
|
+
self[filter_type].filter raw_output_e, filter_e
|
33
|
+
else
|
34
|
+
raise Error['bad-attribute'].new('protocol', 'error', info: {'bad-attribute' => filter_type, 'bad-element' => 'filter'})
|
35
|
+
end
|
36
|
+
else
|
37
|
+
raw_output_e
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private :__subclass_list__
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
require 'hrr_rb_netconf/server/filter/subtree'
|
48
|
+
require 'hrr_rb_netconf/server/filter/xpath'
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# vim: et ts=2 sw=2
|
3
|
+
|
4
|
+
require 'rexml/document'
|
5
|
+
|
6
|
+
module HrrRbNetconf
|
7
|
+
class Server
|
8
|
+
class Filter
|
9
|
+
class Subtree < Filter
|
10
|
+
TYPE = 'subtree'
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def filter raw_output_e, filter_e
|
14
|
+
selected_element_xpaths = []
|
15
|
+
output_xml_doc = REXML::Document.new
|
16
|
+
subtree_e = filter_e.elements[1]
|
17
|
+
filter_recursively(selected_element_xpaths, output_xml_doc, raw_output_e, subtree_e)
|
18
|
+
output_xml_doc.root
|
19
|
+
end
|
20
|
+
|
21
|
+
def content_match_nodes_match_all? content_match_nodes, raw_output_e
|
22
|
+
content_match_nodes.all?{ |child_filter_e|
|
23
|
+
child_filter_attributes = child_filter_e.attributes.to_a.reject{ |attr| (attr.prefix =='' && attr.name == 'xmlns') || attr.prefix == 'xmlns' }
|
24
|
+
raw_output_e.elements.to_a.any?{ |child_raw_output_e|
|
25
|
+
(child_filter_e.namespace == "" || child_filter_e.namespace == child_raw_output_e.namespace) && child_filter_e.name == child_raw_output_e.name && child_filter_e.text == child_raw_output_e.text && (
|
26
|
+
child_filter_attributes.empty? || child_filter_attributes.reject{ |child_filter_attr|
|
27
|
+
child_raw_output_e.attributes.to_a.reject{ |attr| (attr.prefix =='' && attr.name == 'xmlns') || attr.prefix == 'xmlns' }.any?{ |child_raw_output_attr|
|
28
|
+
(child_filter_attr.namespace == "" || child_filter_attr.namespace == child_raw_output_attr.namespace) && child_filter_attr.name == child_raw_output_attr.name && child_filter_attr.value == child_raw_output_attr.value
|
29
|
+
}
|
30
|
+
}
|
31
|
+
)
|
32
|
+
}
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
def add_elem selected_element_xpaths, output_e, raw_output_e, output_e_duplicated
|
37
|
+
if output_e_duplicated
|
38
|
+
xpath, elem = selected_element_xpaths.find{ |xpath, elem| xpath == raw_output_e.xpath }
|
39
|
+
unless xpath
|
40
|
+
child_output_e = output_e.add raw_output_e.clone
|
41
|
+
selected_element_xpaths.push [raw_output_e.xpath, child_output_e]
|
42
|
+
[child_output_e, false]
|
43
|
+
else
|
44
|
+
[elem, true]
|
45
|
+
end
|
46
|
+
else
|
47
|
+
child_output_e = output_e.add raw_output_e.clone
|
48
|
+
selected_element_xpaths.push [raw_output_e.xpath, child_output_e]
|
49
|
+
[child_output_e, false]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def filter_recursively selected_element_xpaths, output_e, raw_output_e, filter_e, options={}
|
54
|
+
if filter_e
|
55
|
+
if raw_output_e.name == filter_e.name
|
56
|
+
# Namespace Selection
|
57
|
+
filter_namespace = options['namespace'] || filter_e.namespace
|
58
|
+
if filter_namespace == nil || filter_namespace == "" || raw_output_e.namespace == filter_namespace
|
59
|
+
# Attribute Match Expressions
|
60
|
+
filter_attributes = filter_e.attributes.to_a.reject{ |attr| (attr.prefix =='' && attr.name == 'xmlns') || attr.prefix == 'xmlns' }
|
61
|
+
if filter_attributes.empty? || filter_attributes.reject{ |filter_attr|
|
62
|
+
raw_output_e.attributes.to_a.reject{ |attr| (attr.prefix =='' && attr.name == 'xmlns') || attr.prefix == 'xmlns' }.any?{ |raw_output_attr|
|
63
|
+
filter_attr.namespace == raw_output_attr.namespace && filter_attr.name == raw_output_attr.name && filter_attr.value == raw_output_attr.value
|
64
|
+
}
|
65
|
+
}.empty?
|
66
|
+
if filter_e.has_elements?
|
67
|
+
# Containment Nodes
|
68
|
+
if filter_e.elements.to_a.select{ |c| c.has_text? }.empty?
|
69
|
+
child_output_e, child_output_e_duplicated = add_elem selected_element_xpaths, output_e, raw_output_e, options['output_e_duplicated']
|
70
|
+
raw_output_e.each_element{ |child_raw_output_e|
|
71
|
+
filter_e.elements.to_a.select{ |c| c.name == child_raw_output_e.name && (c.namespace == "" || c.namespace == child_raw_output_e.namespace) }.each{ |child_filter_e|
|
72
|
+
unless child_output_e_duplicated
|
73
|
+
if selected_element_xpaths.any?{ |xpath, elem| xpath == child_raw_output_e.xpath }
|
74
|
+
child_output_e_duplicated = true
|
75
|
+
end
|
76
|
+
end
|
77
|
+
filter_recursively selected_element_xpaths, child_output_e, child_raw_output_e, child_filter_e, {'namespace' => filter_namespace, 'output_e_duplicated' => child_output_e_duplicated}
|
78
|
+
}
|
79
|
+
}
|
80
|
+
# Content Match Nodes
|
81
|
+
else
|
82
|
+
content_match_nodes = filter_e.elements.to_a.select{ |c| c.has_text? }
|
83
|
+
not_content_match_nodes = filter_e.elements.to_a.reject{ |c| c.has_text? }
|
84
|
+
if content_match_nodes_match_all? content_match_nodes, raw_output_e
|
85
|
+
child_output_e, child_output_e_duplicated = add_elem selected_element_xpaths, output_e, raw_output_e, options['output_e_duplicated']
|
86
|
+
if not_content_match_nodes.empty?
|
87
|
+
raw_output_e.each_element{ |child_raw_output_e|
|
88
|
+
child_filter_e = filter_e.elements.to_a.find{ |c| (c.namespace == "" || child_raw_output_e.namespace == c.namespace) && child_raw_output_e.name == c.name }
|
89
|
+
if child_filter_e
|
90
|
+
filter_recursively selected_element_xpaths, child_output_e, child_raw_output_e, child_filter_e, {'namespace' => filter_namespace, 'output_e_duplicated' => child_output_e_duplicated}
|
91
|
+
else
|
92
|
+
filter_recursively selected_element_xpaths, child_output_e, child_raw_output_e, child_filter_e, {'namespace' => filter_namespace, 'in_filter' => true, 'output_e_duplicated' => child_output_e_duplicated}
|
93
|
+
end
|
94
|
+
}
|
95
|
+
else
|
96
|
+
raw_output_e.each_element{ |child_raw_output_e|
|
97
|
+
child_filter_e = filter_e.elements.to_a.find{ |c| (c.namespace == "" || child_raw_output_e.namespace == c.namespace) && child_raw_output_e.name == c.name }
|
98
|
+
filter_recursively selected_element_xpaths, child_output_e, child_raw_output_e, child_filter_e, {'namespace' => filter_namespace, 'output_e_duplicated' => child_output_e_duplicated}
|
99
|
+
}
|
100
|
+
end
|
101
|
+
else
|
102
|
+
end
|
103
|
+
end
|
104
|
+
else
|
105
|
+
child_output_e, child_output_e_duplicated = add_elem selected_element_xpaths, output_e, raw_output_e, options['output_e_duplicated']
|
106
|
+
if raw_output_e.has_text?
|
107
|
+
child_output_e.text = raw_output_e.text
|
108
|
+
else
|
109
|
+
raw_output_e.each_element{ |child_raw_output_e|
|
110
|
+
filter_recursively selected_element_xpaths, child_output_e, child_raw_output_e, nil, {'namespace' => filter_namespace, 'in_filter' => true, 'output_e_duplicated' => child_output_e_duplicated}
|
111
|
+
}
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
elsif options['in_filter']
|
118
|
+
# Namespace Selection
|
119
|
+
filter_namespace = options['namespace']
|
120
|
+
if filter_namespace == nil || filter_namespace == "" || raw_output_e.namespace == filter_namespace
|
121
|
+
child_output_e, child_output_e_duplicated = add_elem selected_element_xpaths, output_e, raw_output_e, options['output_e_duplicated']
|
122
|
+
if raw_output_e.has_text?
|
123
|
+
child_output_e.text = raw_output_e.text
|
124
|
+
end
|
125
|
+
raw_output_e.each_element{ |child_raw_output_e|
|
126
|
+
filter_recursively selected_element_xpaths, child_output_e, child_raw_output_e, filter_e, {'namespace' => filter_namespace, 'in_filter' => true, 'outout_e_duplicated' => child_output_e_duplicated}
|
127
|
+
}
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|