xml_schema_mapper 0.0.1 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|