roundtrip_xml 0.0.1 → 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 +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
|