xml_schema_mapper 0.0.1 → 0.0.5
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.
- data/.gitignore +1 -0
- data/lib/thor/templates/converter_class.erb +17 -10
- data/lib/thor/templates/converter_spec.erb +8 -7
- data/lib/thor/templates/mapper_class.erb +28 -9
- data/lib/thor/templates/mapper_spec.erb +15 -9
- data/lib/thor/xsd_mappers.rb +66 -21
- data/lib/xml_schema_mapper.rb +99 -23
- data/lib/xml_schema_mapper/builder.rb +69 -27
- data/lib/xml_schema_mapper/element.rb +39 -34
- data/lib/xml_schema_mapper/namespace_resolver.rb +33 -0
- data/lib/xml_schema_mapper/parser.rb +68 -8
- data/lib/xml_schema_mapper/test_builder.rb +84 -0
- data/lib/xml_schema_mapper/version.rb +1 -1
- data/spec/build_xml_spec.rb +3 -3
- data/spec/builder_spec.rb +23 -8
- data/spec/fixtures/UserService.xsd +23 -2
- data/spec/fixtures/common.xsd +1 -1
- data/spec/fixtures/get_first_name.xml +8 -8
- data/spec/fixtures/instance1.xml +8 -8
- data/spec/fixtures/instance_with_arrays.xml +29 -0
- data/spec/fixtures/user_service.rb +113 -4
- data/spec/parse_xml_spec.rb +51 -9
- data/spec/visitor_spec.rb +167 -0
- data/spec/xml_schema_mapper_spec.rb +2 -2
- metadata +40 -42
- data/.idea/.rakeTasks +0 -7
- data/.idea/encodings.xml +0 -5
- data/.idea/misc.xml +0 -8
- data/.idea/modules.xml +0 -9
- data/.idea/scopes/scope_settings.xml +0 -5
- data/.idea/vcs.xml +0 -7
- data/.idea/workspace.xml +0 -459
- data/.idea/xml_schema_mapper.iml +0 -29
data/.gitignore
CHANGED
@@ -1,13 +1,20 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# encoding: utf-8
|
2
|
+
# @note <%= type.annotation.to_s.gsub("\n", "\n# ") %>
|
3
|
+
|
4
|
+
<%- elements.each do |element| -%>
|
5
|
+
<%- (element.annotation || element.type.annotation).each_line do |line| -%>
|
6
|
+
# <%= line %>
|
7
|
+
<%- end -%>
|
8
|
+
# @attr <%= element.name %> [<%= element.type.name %>]
|
9
|
+
<%- end -%>
|
10
|
+
|
11
|
+
<%- if options[:converter_module_name].present? -%>
|
12
|
+
class <%= options[:converter_module_name] %>::<%= converter_name %> < Converter
|
3
13
|
<% else -%>
|
4
|
-
class <%=
|
14
|
+
class <%= converter_name %> < Converter
|
5
15
|
<% end -%>
|
6
|
-
include ModelConverter
|
7
16
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
13
|
-
end
|
17
|
+
<%- elements.each do |element| -%>
|
18
|
+
map mapper: :<%= element.name.underscore %>, model: :<%= element.name.underscore %>
|
19
|
+
<%- end -%>
|
20
|
+
end
|
@@ -1,11 +1,12 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
<%-
|
4
|
-
|
3
|
+
<%- elements.each do |element| -%>
|
4
|
+
# @attr <%= element.name %> [<%= element.type.name %>]
|
5
|
+
<%- end %>
|
6
|
+
|
7
|
+
<%- if options[:converter_module_name].present? -%>
|
8
|
+
describe <%= options[:converter_module_name] %>::<%= converter_name %> do
|
5
9
|
<% else -%>
|
6
|
-
describe <%=
|
10
|
+
describe <%= converter_name %> do
|
7
11
|
<% end -%>
|
8
|
-
|
9
|
-
it { _schema.should be_a LibXML::XML::Schema }
|
10
|
-
it { _type.name.should eql '<%= name %>' }
|
11
|
-
end
|
12
|
+
end
|
@@ -1,16 +1,35 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
<%- unless type.annotation.to_s.blank? -%>
|
2
3
|
# @note <%= type.annotation.to_s.gsub("\n", "\n# ") %>
|
3
|
-
|
4
|
-
<%- elements.each do |element| -%>
|
5
|
-
# @attr <%= element.name %> [<%= element.type.name %>] <%= element.annotation || element.type.annotation %>
|
6
4
|
<%- end -%>
|
7
5
|
|
8
|
-
|
9
|
-
class <%= options[:module_name] %>::<%= name.camelize %>Mapper
|
10
|
-
<% else -%>
|
11
|
-
class <%= name.camelize %>Mapper
|
12
|
-
<% end -%>
|
6
|
+
class <%= mapper_name %>
|
13
7
|
include XmlSchemaMapper
|
14
8
|
schema '<%= schema_path %>'
|
15
9
|
type '<%= name %>'
|
16
|
-
|
10
|
+
|
11
|
+
<%- elements.each do |element| -%>
|
12
|
+
<%- element_annotation(element).split("\n").delete_if(&:blank?).each do |comment| -%>
|
13
|
+
# <%= comment %>
|
14
|
+
<%- end -%>
|
15
|
+
# minOccurs: <%= element.min_occurs %>, maxOccurs: <%= element.max_occurs %>
|
16
|
+
attr_accessor :<%= element.name.underscore %>
|
17
|
+
<%- end -%>
|
18
|
+
|
19
|
+
<%- subclasses.each do |subclass, type| -%>
|
20
|
+
class <%= subclass.split('::').map(&:camelize).join('::') %>
|
21
|
+
include XmlSchemaMapper
|
22
|
+
schema '<%= schema_path %>'
|
23
|
+
annonymus_type '<%= [name.camelize, subclass].join('::') %>'
|
24
|
+
|
25
|
+
<%- type.elements.values.each do |element| -%>
|
26
|
+
<%- element_annotation(element).split("\n").delete_if(&:blank?).each do |comment| -%>
|
27
|
+
# <%= comment %>
|
28
|
+
<%- end -%>
|
29
|
+
# minOccurs: <%= element.min_occurs %>, maxOccurs: <%= element.max_occurs %>
|
30
|
+
attr_accessor :<%= element.name.underscore %>
|
31
|
+
<%- end -%>
|
32
|
+
end
|
33
|
+
|
34
|
+
<%- end unless subclasses.empty? -%>
|
35
|
+
end
|
@@ -1,16 +1,22 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require 'spec_helper'
|
2
|
+
require "xml_schema_mapper/test_builder"
|
3
3
|
|
4
4
|
<%- elements.each do |element| -%>
|
5
|
-
# @attr <%= element.name %> [<%= element.type.name %>]
|
5
|
+
# @attr <%= element.name %> [<%= element.type.name %>]
|
6
6
|
<%- end %>
|
7
7
|
|
8
|
-
require 'spec_helper'
|
9
|
-
|
10
8
|
<%- if options[:module_name].present? -%>
|
11
|
-
describe <%= options[:module_name] %>::<%= name.camelize %> do
|
9
|
+
describe <%= options[:module_name] %>::<%= name.camelize %>Mapper do
|
12
10
|
<% else -%>
|
13
|
-
describe <%= name.camelize %> do
|
11
|
+
describe <%= name.underscore.camelize %>Mapper do
|
14
12
|
<% end -%>
|
15
|
-
|
16
|
-
|
13
|
+
|
14
|
+
include XmlSchemaMapper::TestBuilder::Helper
|
15
|
+
|
16
|
+
subject { build_described_mapper }
|
17
|
+
|
18
|
+
it "should be self-compatible xml <-> object" do
|
19
|
+
described_class.parse(subject.to_xml).to_xml.should eql subject.to_xml
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
data/lib/thor/xsd_mappers.rb
CHANGED
@@ -4,19 +4,15 @@ require "thor/group"
|
|
4
4
|
module XsdMappers
|
5
5
|
class CLI < Thor
|
6
6
|
|
7
|
-
desc '
|
7
|
+
desc 'generate path/to/xsd', 'generate mappers for xsd types'
|
8
8
|
method_option :module_name, default: ''
|
9
|
-
|
10
|
-
|
11
|
-
Mappers.new([name, schema_path, destination]).invoke_all
|
12
|
-
end
|
13
|
-
end
|
9
|
+
method_option :converter_module_name, default: ''
|
10
|
+
method_option :'skip-converters', type: :boolean
|
14
11
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
Converters.new([name, schema_path, destination], options.merge(attributes: type.elements.keys)).invoke_all
|
12
|
+
def generate(schema_path)
|
13
|
+
schema(schema_path).types.each do |name, _|
|
14
|
+
Mappers.new([name, schema_path], options).invoke_all
|
15
|
+
Converters.new([name, schema_path], options).invoke_all unless options[:'skip-converters']
|
20
16
|
end
|
21
17
|
end
|
22
18
|
|
@@ -34,7 +30,6 @@ module XsdMappers
|
|
34
30
|
# Define arguments and options
|
35
31
|
argument :name
|
36
32
|
argument :schema_path
|
37
|
-
argument :destination, default: './'
|
38
33
|
class_option :module_name, default: ''
|
39
34
|
class_option :override, default: false
|
40
35
|
class_option :base_type, default: nil
|
@@ -44,20 +39,27 @@ module XsdMappers
|
|
44
39
|
File.dirname(__FILE__)
|
45
40
|
end
|
46
41
|
|
42
|
+
def module_path
|
43
|
+
options[:module_name] ? options[:module_name].underscore : ""
|
44
|
+
end
|
45
|
+
|
47
46
|
def create_lib_file
|
48
|
-
|
47
|
+
filename = "#{name.underscore}_mapper.rb"
|
48
|
+
template('templates/mapper_class.erb', File.join('app/mappers/', module_path, filename))
|
49
49
|
end
|
50
50
|
|
51
51
|
def create_test_file
|
52
|
-
test
|
52
|
+
test = options[:test_framework] == "test" ? :test : :spec
|
53
|
+
filename = "#{name.underscore}_mapper_#{test}.rb"
|
53
54
|
with_padding do
|
54
|
-
template 'templates/mapper_spec.erb', "
|
55
|
+
template 'templates/mapper_spec.erb', File.join("#{test}/mappers/", module_path, filename)
|
55
56
|
end
|
56
57
|
end
|
57
58
|
|
58
59
|
protected
|
59
|
-
|
60
|
-
|
60
|
+
|
61
|
+
def subclasses
|
62
|
+
type.annonymus_subtypes_recursively.inject({ }, &:merge)
|
61
63
|
end
|
62
64
|
|
63
65
|
def schema
|
@@ -71,21 +73,64 @@ module XsdMappers
|
|
71
73
|
def type
|
72
74
|
@type ||= schema.types[name]
|
73
75
|
end
|
76
|
+
|
77
|
+
def element_annotation(element)
|
78
|
+
type = element.type.name || "#{element.name}"
|
79
|
+
comment = element.annotation || element.type.annotation
|
80
|
+
|
81
|
+
if is_a_simple?(element.type)
|
82
|
+
"#{comment}\n" <<
|
83
|
+
"@return [#{type.camelize}]"
|
84
|
+
else
|
85
|
+
"#{comment}\n" <<
|
86
|
+
"@return [#{module_name}#{type.camelize}Mapper]"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def is_a_simple?(type)
|
91
|
+
[LibXML::XML::Schema::Types::XML_SCHEMA_TYPE_SIMPLE,
|
92
|
+
LibXML::XML::Schema::Types::XML_SCHEMA_TYPE_BASIC].include?(type.kind)
|
93
|
+
end
|
94
|
+
|
95
|
+
def module_name
|
96
|
+
if options[:module_name].presence
|
97
|
+
"#{options[:module_name]}::"
|
98
|
+
else
|
99
|
+
""
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def mapper_name
|
104
|
+
class_name = "#{name.underscore.camelize}Mapper"
|
105
|
+
"#{module_name}#{class_name}"
|
106
|
+
end
|
74
107
|
end
|
75
108
|
|
76
109
|
class Converters < Mappers
|
77
110
|
class_option :attributes, type: :array
|
111
|
+
class_option :converter_module_name, default: ""
|
78
112
|
class_option :force, default: false
|
113
|
+
class_option :skip, default: true
|
114
|
+
|
115
|
+
def module_path
|
116
|
+
options[:converter_module_name] ? options[:converter_module_name].underscore : ""
|
117
|
+
end
|
79
118
|
|
80
119
|
def create_lib_file
|
81
|
-
|
120
|
+
filename = "#{name.underscore}_converter.rb"
|
121
|
+
template('templates/converter_class.erb', File.join('app/converters/', module_path, filename))
|
82
122
|
end
|
83
123
|
|
84
124
|
def create_test_file
|
85
|
-
test
|
125
|
+
test = options[:test_framework] == "test" ? :test : :spec
|
126
|
+
filename = "#{name.underscore}_converter_#{test}.rb"
|
86
127
|
with_padding do
|
87
|
-
template 'templates/converter_spec.erb', "
|
128
|
+
template 'templates/converter_spec.erb', File.join("#{test}/converters/", module_path, filename)
|
88
129
|
end
|
89
130
|
end
|
131
|
+
|
132
|
+
def converter_name
|
133
|
+
"#{name.underscore.camelize}Converter"
|
134
|
+
end
|
90
135
|
end
|
91
|
-
end
|
136
|
+
end
|
data/lib/xml_schema_mapper.rb
CHANGED
@@ -4,46 +4,52 @@ require "nokogiri"
|
|
4
4
|
require "active_support/concern"
|
5
5
|
require "active_support/core_ext/class"
|
6
6
|
require "active_support/core_ext/module/delegation"
|
7
|
+
require "active_support/core_ext/object/blank"
|
8
|
+
require "active_support/core_ext/string/inflections"
|
7
9
|
require "virtus"
|
8
10
|
|
9
11
|
require "xml_schema_mapper/element"
|
10
12
|
require "xml_schema_mapper/parser"
|
11
13
|
require "xml_schema_mapper/builder"
|
14
|
+
require "xml_schema_mapper/namespace_resolver"
|
12
15
|
|
13
16
|
module XmlSchemaMapper
|
14
17
|
extend ActiveSupport::Concern
|
15
|
-
mattr_accessor :
|
16
|
-
self.default_class = String
|
18
|
+
mattr_accessor :namespace_resolver_class
|
17
19
|
|
18
20
|
included do
|
19
21
|
class_attribute :_schema
|
20
22
|
class_attribute :_type
|
21
|
-
class_attribute :
|
22
|
-
self.elements = []
|
23
|
+
class_attribute :namespace_resolver_class
|
23
24
|
include Virtus
|
24
25
|
end
|
25
26
|
|
26
27
|
module ClassMethods
|
27
|
-
def schema(location)
|
28
|
-
|
28
|
+
def schema(location=nil)
|
29
|
+
if location
|
30
|
+
self._schema = LibXML::XML::Schema.cached(location)
|
31
|
+
else
|
32
|
+
self._schema
|
33
|
+
end
|
29
34
|
end
|
30
35
|
|
31
|
-
def type(name)
|
36
|
+
def type(name=nil)
|
32
37
|
raise(%Q{call "schema 'path/to/your/File.xsd'" before calling "type"}) unless _schema
|
33
|
-
|
34
|
-
|
38
|
+
if name
|
39
|
+
self._type = _schema.types[name]
|
40
|
+
attr_accessor :attrs
|
41
|
+
else
|
42
|
+
self._type
|
43
|
+
end
|
35
44
|
end
|
36
45
|
|
37
|
-
def
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
raise [e.method_name, e.klass, e.type.name].inspect
|
45
|
-
end
|
46
|
-
end
|
46
|
+
def annonymus_type(name)
|
47
|
+
raise(%Q{call "schema 'path/to/your/File.xsd'" before calling "type"}) unless _schema
|
48
|
+
path = name.split('::')
|
49
|
+
type = _schema.types[path.shift]
|
50
|
+
self._type = path.map do |n|
|
51
|
+
type = type.elements[n].type if type
|
52
|
+
end.last
|
47
53
|
end
|
48
54
|
|
49
55
|
def parse(string_or_node)
|
@@ -58,20 +64,90 @@ module XmlSchemaMapper
|
|
58
64
|
raise(ArgumentError, "param must be a String or Nokogiri::XML::Node, but \"#{string_or_node.inspect}\" given")
|
59
65
|
end
|
60
66
|
end
|
67
|
+
|
68
|
+
def elements
|
69
|
+
@elements ||= type.elements.values.map do |element|
|
70
|
+
XmlSchemaMapper::Element.new(element)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def attrs
|
75
|
+
@attrs ||= type.attributes
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
delegate :first, :last, :each, :length, :size, :all?, :any?, :one?, :empty?, to: :element_values
|
80
|
+
|
81
|
+
def [](key)
|
82
|
+
send(key)
|
83
|
+
end
|
84
|
+
|
85
|
+
def []=(key, val)
|
86
|
+
send(:"#{key}=", val)
|
87
|
+
end
|
88
|
+
|
89
|
+
def accept(visitor, *args)
|
90
|
+
visitor.visit(self, *args)
|
91
|
+
end
|
92
|
+
|
93
|
+
def simple?
|
94
|
+
_type.simple?
|
95
|
+
end
|
96
|
+
|
97
|
+
def values
|
98
|
+
_type.facets.map &:value
|
99
|
+
end
|
100
|
+
|
101
|
+
def type
|
102
|
+
self.class.type
|
103
|
+
end
|
104
|
+
|
105
|
+
def schema
|
106
|
+
self.class.schema
|
61
107
|
end
|
62
108
|
|
63
109
|
def element_names
|
64
|
-
elements.
|
110
|
+
elements.keys
|
65
111
|
end
|
66
112
|
|
67
|
-
def
|
68
|
-
|
113
|
+
def element_values
|
114
|
+
elements.values
|
115
|
+
end
|
116
|
+
|
117
|
+
def elements
|
118
|
+
type.elements.values.inject({ }) do |hash, element|
|
119
|
+
hash.merge element.name.underscore.to_sym => send(element.name.underscore.to_sym)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def to_xml(options = { })
|
124
|
+
xml_document.root.to_xml({ :encoding => 'UTF-8' }.merge(options))
|
69
125
|
end
|
70
126
|
|
71
127
|
def xml_document
|
72
128
|
document = XmlSchemaMapper::Builder.create_document(_type)
|
73
|
-
|
129
|
+
|
130
|
+
ns = namespace_resolver.find_by_href (global_element || _type).namespace
|
131
|
+
document.root.namespace = document.root.add_namespace_definition(ns.prefix, ns.href)
|
132
|
+
|
133
|
+
builder = XmlSchemaMapper::Builder.new(self, document.root, namespace_resolver)
|
74
134
|
builder.build
|
75
135
|
builder.document
|
76
136
|
end
|
137
|
+
|
138
|
+
def namespace_resolver
|
139
|
+
case
|
140
|
+
when self.class.namespace_resolver_class
|
141
|
+
self.class.namespace_resolver_class.new(schema.namespaces)
|
142
|
+
when XmlSchemaMapper.namespace_resolver_class
|
143
|
+
XmlSchemaMapper.namespace_resolver_class.new(schema.namespaces)
|
144
|
+
else
|
145
|
+
schema.namespaces
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def global_element
|
150
|
+
schema.elements.values.find { |e| e.type.name == _type.name }
|
151
|
+
end
|
152
|
+
|
77
153
|
end
|
@@ -4,29 +4,39 @@ end
|
|
4
4
|
module XmlSchemaMapper
|
5
5
|
class Builder
|
6
6
|
|
7
|
-
attr_reader :document, :parent
|
8
|
-
|
9
|
-
|
7
|
+
attr_reader :document, :parent, :namespace_resolver
|
8
|
+
|
9
|
+
def initialize(source, parent, namespace_resolver)
|
10
|
+
@parent = parent.is_a?(Nokogiri::XML::Document) ? parent.root : parent
|
11
|
+
@document = parent.document
|
12
|
+
@source = source
|
13
|
+
@klass = source.class
|
14
|
+
@namespace_resolver = namespace_resolver
|
15
|
+
@schema = @klass._schema
|
16
|
+
end
|
10
17
|
|
11
|
-
def
|
12
|
-
@
|
13
|
-
@document = parent.document
|
14
|
-
@source = source
|
15
|
-
@klass = source.class
|
16
|
-
@schema = @klass._schema
|
18
|
+
def elements
|
19
|
+
@klass.type.elements.values.map { |e| XmlSchemaMapper::Element.new e }
|
17
20
|
end
|
18
21
|
|
19
22
|
def build
|
20
23
|
elements.each do |element|
|
21
24
|
add_element_namespace_to_root!(element)
|
22
25
|
node = create_node(element)
|
23
|
-
|
26
|
+
|
27
|
+
parent << node if can_add?(element, node)
|
28
|
+
|
29
|
+
if node.is_a?(Nokogiri::XML::NodeSet)
|
30
|
+
node.each { |n| n.namespace = nil if element.namespace.nil? }
|
31
|
+
else
|
32
|
+
node.namespace = nil if element.namespace.nil?
|
33
|
+
end
|
24
34
|
end
|
25
35
|
self
|
26
36
|
end
|
27
37
|
|
28
|
-
def
|
29
|
-
|
38
|
+
def can_add?(element, node)
|
39
|
+
node.is_a?(Nokogiri::XML::NodeSet) || node.content.present?
|
30
40
|
end
|
31
41
|
|
32
42
|
private
|
@@ -41,50 +51,82 @@ module XmlSchemaMapper
|
|
41
51
|
|
42
52
|
def setup_namespace(element)
|
43
53
|
yield.tap do |node|
|
44
|
-
|
45
|
-
|
54
|
+
case node
|
55
|
+
when Nokogiri::XML::NodeSet
|
56
|
+
node.each { |n| n.namespace = find_namespace_definition(element.namespace) }
|
57
|
+
when NilClass
|
58
|
+
else
|
59
|
+
node.namespace = find_namespace_definition(element.namespace)
|
60
|
+
end
|
46
61
|
end
|
47
62
|
end
|
48
63
|
|
49
64
|
def simple_node(element)
|
50
|
-
|
65
|
+
value = source.send(element.reader)
|
66
|
+
if value.is_a? Array
|
67
|
+
list = value.map do |i|
|
68
|
+
document.create_element(element.name, i)
|
69
|
+
end
|
70
|
+
Nokogiri::XML::NodeSet.new(document, list)
|
71
|
+
else
|
72
|
+
document.create_element(element.name, element.content_from(source))
|
73
|
+
end
|
51
74
|
end
|
52
75
|
|
53
76
|
def complex_node(element)
|
54
77
|
object = source.send(element.reader)
|
55
78
|
complex_root_node = document.create_element(element.name)
|
56
79
|
|
80
|
+
complex_children(complex_root_node, object)
|
81
|
+
rescue NoToXmlError
|
82
|
+
raise("object of #{source.class}##{element.reader} should respond to :to_xml")
|
83
|
+
end
|
84
|
+
|
85
|
+
def complex_children(complex_root_node, object)
|
57
86
|
if object.is_a?(XmlSchemaMapper)
|
58
87
|
complex_node_from_mapper(complex_root_node, object)
|
59
88
|
else
|
60
89
|
complex_node_from_xml(complex_root_node, object)
|
61
90
|
end
|
62
|
-
rescue NoToXmlError
|
63
|
-
raise("object of #{source.class}##{element.reader} should respond to :to_xml")
|
64
91
|
end
|
65
92
|
|
66
|
-
def complex_node_from_xml(
|
67
|
-
return
|
68
|
-
if object.
|
69
|
-
|
93
|
+
def complex_node_from_xml(complex_root_node, object)
|
94
|
+
return complex_root_node if object.nil?
|
95
|
+
if object.is_a?(Array)
|
96
|
+
list = object.map do |o|
|
97
|
+
complex_node_item = complex_root_node.dup
|
98
|
+
complex_children(complex_node_item, o)
|
99
|
+
end
|
100
|
+
Nokogiri::XML::NodeSet.new(complex_root_node.document, list)
|
101
|
+
elsif object.respond_to?(:to_xml)
|
102
|
+
complex_root_node << object.to_xml
|
70
103
|
else
|
71
104
|
raise NoToXmlError
|
72
105
|
end
|
73
106
|
end
|
74
107
|
|
75
|
-
def complex_node_from_mapper(
|
76
|
-
XmlSchemaMapper::Builder.build(object,
|
108
|
+
def complex_node_from_mapper(complex_root_node, object)
|
109
|
+
XmlSchemaMapper::Builder.build(object, complex_root_node, namespace_resolver).parent
|
77
110
|
end
|
78
111
|
|
79
112
|
def add_element_namespace_to_root!(element)
|
80
113
|
if element.namespace
|
81
|
-
|
114
|
+
|
115
|
+
ns = find_namespace(element)
|
82
116
|
raise "prefix for namespace #{element.namespace.inspect} not found" unless ns
|
83
117
|
|
84
118
|
document.root.add_namespace(ns.prefix, ns.href)
|
85
119
|
end
|
86
120
|
end
|
87
121
|
|
122
|
+
def find_namespace(element)
|
123
|
+
if namespace_resolver
|
124
|
+
namespace_resolver.find_by_href(element.namespace)
|
125
|
+
else
|
126
|
+
schema.namespaces.find_by_href(element.namespace)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
88
130
|
def find_namespace_definition(href)
|
89
131
|
document.root.namespace_definitions.find { |ns| ns.href == href }
|
90
132
|
end
|
@@ -97,9 +139,9 @@ module XmlSchemaMapper
|
|
97
139
|
end
|
98
140
|
end
|
99
141
|
|
100
|
-
def self.build(mapper, parent)
|
101
|
-
XmlSchemaMapper::Builder.new(mapper, parent).build
|
142
|
+
def self.build(mapper, parent, namespace_resolver)
|
143
|
+
XmlSchemaMapper::Builder.new(mapper, parent, namespace_resolver).build
|
102
144
|
end
|
103
145
|
|
104
146
|
end
|
105
|
-
end
|
147
|
+
end
|