roundtrip_xml 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/roundtrip_xml.rb +0 -1
- data/lib/roundtrip_xml/dsl_builder.rb +8 -3
- data/lib/roundtrip_xml/dsl_runtime.rb +3 -3
- data/lib/roundtrip_xml/root_cleanroom.rb +1 -1
- data/lib/roundtrip_xml/roxml_builder.rb +18 -14
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 850975cc32a5c9ced95414160cfad097ce92e9e8
|
4
|
+
data.tar.gz: 671db4137da1eb5905eba7cdc2cf9c25c8070fef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bff3c1deb59c3b10fc8d28f85dab0af750505fa1087644b70974ed1603e2149738c335bf741a3e65fa5bb399fd4ec9832a7d78e32dc4ca5e3303e7b0cf88884f
|
7
|
+
data.tar.gz: 179aee0f43f83b93bef5cd047ff78b5f50b863a0470768cb03b787be956cfe7f783b30e8c6432decea7d7e352ac6f74dfdce0a653236f1317508d2ca7648b95a
|
data/lib/roundtrip_xml.rb
CHANGED
@@ -13,16 +13,21 @@ class DslBuilder
|
|
13
13
|
|
14
14
|
def write_attrs(clazz, xml, inset='')
|
15
15
|
clazz.roxml_attrs.inject('') do |out, attr|
|
16
|
+
# if no xml was found for the given selector, the attribute was optional
|
17
|
+
return '' unless xml
|
16
18
|
accessor = attr.accessor
|
17
19
|
selector = attr.name
|
18
20
|
|
19
21
|
if attr.sought_type == :text
|
20
22
|
out += inset + "#{accessor} '#{xml.xpath(selector)[0].content}'\n"
|
21
23
|
elsif attr.sought_type == :attr
|
22
|
-
|
24
|
+
child_attribute = xml.attributes[selector]
|
25
|
+
out += inset + "#{accessor} '#{child_attribute.content}'\n" if child_attribute
|
23
26
|
elsif !attr.array?
|
24
|
-
|
25
|
-
|
27
|
+
child_element = xml.children.find {|c| c.name == selector}
|
28
|
+
if child_element
|
29
|
+
out += inset + "#{accessor} do\n#{write_attrs attr.sought_type, child_element, inset + ' '}#{inset}end\n"
|
30
|
+
end
|
26
31
|
else
|
27
32
|
xml.xpath(selector).each do |node|
|
28
33
|
out += inset + "#{accessor} do\n#{write_attrs attr.sought_type, node, inset + ' '}#{inset}end\n"
|
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'roxml'
|
2
2
|
require 'nokogiri'
|
3
|
-
require '
|
4
|
-
require '
|
5
|
-
require '
|
3
|
+
require 'roundtrip_xml/roxml_builder'
|
4
|
+
require 'roundtrip_xml/root_cleanroom'
|
5
|
+
require 'roundtrip_xml/base_cleanroom'
|
6
6
|
# Class which evaluates DSL and read XML files to populate the namespace with classes
|
7
7
|
class DslRuntime
|
8
8
|
def initialize()
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# require 'roxml'
|
2
2
|
require 'nokogiri'
|
3
|
-
require '
|
3
|
+
require 'roundtrip_xml/plain_accessors'
|
4
4
|
# Builds dynamic classes based on an XML file.
|
5
5
|
# Classes that already exist in the DslRuntime instance are modified if necessary, not overridden.
|
6
6
|
class RoxmlBuilder
|
@@ -22,16 +22,18 @@ class RoxmlBuilder
|
|
22
22
|
end
|
23
23
|
|
24
24
|
@generated_classes[ name_to_sym(@root.name)] = @root_class
|
25
|
+
@nodes = {}
|
25
26
|
end
|
26
27
|
def build_classes
|
27
28
|
# @root_class.xml_name (@root.name)
|
28
|
-
@root.
|
29
|
+
@root.attributes.values.to_a.concat(@root.children.to_a).each do |child|
|
29
30
|
default_opts = {from:child.name}
|
30
31
|
if is_leaf_element?(child)
|
31
32
|
add_accessor name_to_sym(child.name, true), default_opts, @root
|
32
33
|
elsif child.type == Nokogiri::XML::Node::ATTRIBUTE_NODE
|
33
34
|
add_accessor name_to_sym(child.name, true), {from: "@#{child.name}"}, @root
|
34
|
-
|
35
|
+
elsif child.type == Nokogiri::XML::Node::ELEMENT_NODE
|
36
|
+
# making sure that child is an element here ensures text nodes don't get processed here
|
35
37
|
builder = RoxmlBuilder.new child, @generated_classes
|
36
38
|
new_classes = builder.build_classes
|
37
39
|
child_name = name_to_sym(child.name, true)
|
@@ -52,30 +54,23 @@ class RoxmlBuilder
|
|
52
54
|
end
|
53
55
|
|
54
56
|
|
55
|
-
def add_accessor(name, opts = {}, node
|
57
|
+
def add_accessor(name, opts = {}, node)
|
56
58
|
attrs = @root_class.roxml_attrs
|
57
59
|
attr = attrs.find do |a|
|
58
60
|
a.accessor.to_sym == name
|
59
61
|
end
|
60
62
|
# if class already has xml attribute, delete the old version and add the new version
|
61
63
|
|
62
|
-
if attr
|
63
|
-
if node
|
64
|
+
if attr
|
65
|
+
if node_has_child?(node, attr.accessor.to_sym)
|
64
66
|
@root_class.instance_variable_set(:@roxml_attrs, attrs.select {|i| i != attr })
|
65
67
|
new_attr_type = opts[:as]
|
66
68
|
# add a new attribute with the array type.
|
67
69
|
@root_class.xml_accessor name, opts.merge({as: [new_attr_type]})
|
68
70
|
end
|
69
|
-
# attr_type = attr.sought_type
|
70
|
-
# new_attr_type = opts[:as]
|
71
|
-
# if new_attr_type && attr_type != :text && new_attr_type.tag_name == attr_type.tag_name
|
72
|
-
# # remove `attr` from the class's attributes
|
73
|
-
# @root_class.instance_variable_set(:@roxml_attrs, attrs.select {|i| i != attr })
|
74
|
-
# # add a new attribute with the array type.
|
75
|
-
# @root_class.xml_accessor name, opts.merge({as: [new_attr_type]})
|
76
|
-
# end
|
77
71
|
else
|
78
72
|
@root_class.xml_accessor name, opts
|
73
|
+
add_child_to_node(node, name)
|
79
74
|
end
|
80
75
|
end
|
81
76
|
|
@@ -85,4 +80,13 @@ class RoxmlBuilder
|
|
85
80
|
element.attributes.size == 0 &&
|
86
81
|
element.children.select {|c| c.type == Nokogiri::XML::Node::ELEMENT_NODE}.empty?
|
87
82
|
end
|
83
|
+
|
84
|
+
def node_has_child?(node, child)
|
85
|
+
@nodes[node.path] && @nodes[node.path][child]
|
86
|
+
end
|
87
|
+
|
88
|
+
def add_child_to_node(node, child)
|
89
|
+
@nodes[node.path] ||= {}
|
90
|
+
@nodes[node.path][child] = true
|
91
|
+
end
|
88
92
|
end
|