xml-fu 0.1.1 → 0.1.2

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/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ ### 0.1.2
2
+
3
+ * Additional nesting support
4
+ * Further encapsulated functionality into Node
5
+ * xml.tag! is only used in Node
6
+ * Array collection vs content logic moved to Node
7
+ * Hash iteration logic reduced to a single Node call
8
+ * Node
9
+ * New attribute: "content_type"
10
+ * Special tag characters (\*, \/, !) can be mixed and matched
11
+ * "foo/\*" will return a collection of <foo/> siblings
12
+ * 12 new spec tests
13
+ * Removed development dependencies for:
14
+ * autotest
15
+ * mocha
16
+
17
+ ### 0.1.1
18
+
19
+ * Rescue false positives when setting Node.value due to interaction with ActiveSupport
20
+
1
21
  ### 0.1.0
2
22
 
3
23
  * Initial version. born as a replacement of
data/lib/xml-fu/array.rb CHANGED
@@ -24,10 +24,6 @@ module XmlFu
24
24
  raise(MissingKeyException, "Key name missing for collection") if key.empty?
25
25
 
26
26
  case
27
- when key[-1,1] == "/"
28
- xml << Node.new(key, nil, attributes).to_xml
29
- when ::Hash === item
30
- xml.tag!(key, attributes) { xml << Hash.to_xml(item,options) }
31
27
  when ::Array === item
32
28
  xml << Array.to_xml(item.flatten,options)
33
29
  else
@@ -42,9 +38,10 @@ module XmlFu
42
38
  xml << Array.to_xml(item, options)
43
39
  when XmlFu.infer_simple_value_nodes == true
44
40
  xml << infer_node(item, attributes)
41
+ when item.respond_to?(:to_xml)
42
+ xml << item.to_xml
45
43
  else
46
- # only act on item if it responds to to_xml
47
- xml << item.to_xml if item.respond_to?(:to_xml)
44
+ # unknown xml tranfromation process
48
45
  end
49
46
  end
50
47
  end
@@ -83,11 +80,14 @@ module XmlFu
83
80
 
84
81
  if item.respond_to?(:keys)
85
82
  filtered = Hash.filter(item)
86
- attributes = filtered.last
87
- item_content = filtered.first
83
+ item_content, attributes = filtered.first, filtered.last
88
84
  end
89
85
 
90
- yield xml, key, item_content, attributes
86
+ item_name = ( Symbol === key ?
87
+ XmlFu::Node.symbol_conversion_algorithm.call(key) :
88
+ key.to_s )
89
+
90
+ yield xml, item_name, item_content, attributes
91
91
  end
92
92
 
93
93
  xml.target!
data/lib/xml-fu/hash.rb CHANGED
@@ -11,33 +11,8 @@ module XmlFu
11
11
 
12
12
  # Convert Hash to XML String
13
13
  def self.to_xml(hash, options={})
14
- each_with_xml hash do |xml, key, value, attributes|
15
- # Use symbol conversion algorithm to set tag name
16
- tag_name = ( Symbol === key ?
17
- XmlFu::Node.symbol_conversion_algorithm.call(key) :
18
- key.to_s )
19
-
20
- case
21
- when tag_name[-1,1] == "/"
22
- xml << Node.new(tag_name, nil, attributes).to_xml
23
- when ::Array === value
24
- if tag_name[-1,1] == '*'
25
- options.merge!({
26
- :content_type => "collection",
27
- :key => tag_name.chop,
28
- :attributes => attributes
29
- })
30
- # Collection is merely a set of sibling nodes
31
- xml << Array.to_xml(value.flatten, options)
32
- else
33
- # Contents will contain a parent node
34
- xml.tag!(tag_name, attributes) { xml << Array.to_xml(value, options) }
35
- end
36
- when ::Hash === value
37
- xml.tag!(tag_name, attributes) { xml << Hash.to_xml(value, options) }
38
- else
39
- xml << Node.new(tag_name, value, attributes).to_xml
40
- end
14
+ each_with_xml hash do |xml, name, value, attributes|
15
+ xml << Node.new(name, value, attributes).to_xml
41
16
  end
42
17
  end#self.to_xml
43
18
 
@@ -72,11 +47,15 @@ module XmlFu
72
47
  # yank the attribute keys into their own hash
73
48
  if value.respond_to?(:keys)
74
49
  filtered = Hash.filter(value)
75
- node_attrs = filtered.last
76
- node_value = filtered.first
50
+ node_value, node_attrs = filtered.first, filtered.last
77
51
  end
78
52
 
79
- yield xml, key, node_value, node_attrs
53
+ # Use symbol conversion algorithm to set tag name
54
+ node_name = ( Symbol === key ?
55
+ XmlFu::Node.symbol_conversion_algorithm.call(key) :
56
+ key.to_s )
57
+
58
+ yield xml, node_name, node_value, node_attrs
80
59
  end
81
60
 
82
61
  xml.target!
data/lib/xml-fu/node.rb CHANGED
@@ -39,6 +39,7 @@ module XmlFu
39
39
 
40
40
  attr_accessor :escape_xml
41
41
  attr_accessor :self_closing
42
+ attr_accessor :content_type
42
43
 
43
44
  # Create XmlFu::Node object
44
45
  # @param [String, Symbol] name Name of node
@@ -47,6 +48,7 @@ module XmlFu
47
48
  def initialize(name, value, attributes={})
48
49
  @escape_xml = true
49
50
  @self_closing = false
51
+ @content_type = "container"
50
52
  self.attributes = attributes
51
53
  self.value = value
52
54
  self.name = name
@@ -85,21 +87,25 @@ module XmlFu
85
87
  def name_parse_special_characters(val)
86
88
  use_this = val.dup
87
89
 
88
- # Will this be a self closing node?
89
- if use_this.to_s[-1,1] == '/'
90
- @self_closing = true
91
- use_this.chop!
92
- end
93
-
94
- # Will this node contain escaped XML?
95
- if use_this.to_s[-1,1] == '!'
96
- @escape_xml = false
97
- use_this.chop!
98
- end
99
-
100
90
  # Ensure that we don't have special characters at end of name
101
91
  while ["!","/","*"].include?(use_this.to_s[-1,1]) do
102
- use_this.chop!
92
+ # Will this node contain escaped XML?
93
+ if use_this.to_s[-1,1] == '!'
94
+ @escape_xml = false
95
+ use_this.chop!
96
+ end
97
+
98
+ # Will this be a self closing node?
99
+ if use_this.to_s[-1,1] == '/'
100
+ @self_closing = true
101
+ use_this.chop!
102
+ end
103
+
104
+ # Will this node contain a collection of sibling nodes?
105
+ if use_this.to_s[-1,1] == '*'
106
+ @content_type = "collection"
107
+ use_this.chop!
108
+ end
103
109
  end
104
110
 
105
111
  return use_this
@@ -107,16 +113,22 @@ module XmlFu
107
113
 
108
114
  # Custom Setter for @value instance method
109
115
  def value=(val)
110
- if DateTime === val || Time === val || Date === val
111
- @value = val.strftime XS_DATETIME_FORMAT
112
- elsif val.respond_to?(:to_datetime)
113
- @value = val.to_datetime
114
- elsif val.respond_to?(:call)
115
- @value = val.call
116
- elsif val.nil?
117
- @value = nil
116
+ case val
117
+ when ::Hash then @value = val
118
+ when ::Array then @value = val
119
+ when ::DateTime then @value = val.strftime XS_DATETIME_FORMAT
120
+ when ::Time then @value = val.strftime XS_DATETIME_FORMAT
121
+ when ::Date then @value = val.strftime XS_DATETIME_FORMAT
118
122
  else
119
- @value = val.to_s
123
+ if val.respond_to?(:to_datetime)
124
+ @value = val.to_datetime
125
+ elsif val.respond_to?(:call)
126
+ @value = val.call
127
+ elsif val.nil?
128
+ @value = nil
129
+ else
130
+ @value = val.to_s
131
+ end
120
132
  end
121
133
  rescue => e
122
134
  @value = val.to_s
@@ -133,9 +145,27 @@ module XmlFu
133
145
  def to_xml
134
146
  xml = Builder::XmlMarkup.new
135
147
  case
136
- when @self_closing then xml.tag!(@name, @attributes)
137
- when @value.nil? then xml.tag!(@name, @attributes.merge!("xsi:nil" => "true"))
138
- else xml.tag!(@name, @attributes) { xml << self.value }
148
+ when @self_closing && @content_type == 'container'
149
+ xml.tag!(@name, @attributes)
150
+ when @value.nil?
151
+ xml.tag!(@name, @attributes.merge!("xsi:nil" => "true"))
152
+ when ::Hash === @value
153
+ xml.tag!(@name, @attributes) { xml << XmlFu::Hash.to_xml(@value) }
154
+ when ::Array === @value
155
+ case @content_type
156
+ when "collection"
157
+ xml << XmlFu::Array.to_xml(@value.flatten, {
158
+ :key => (@self_closing ? "#{@name}/" : @name),
159
+ :attributes => @attributes,
160
+ :content_type => "collection"
161
+ })
162
+ when "container"
163
+ xml.tag!(@name, @attributes) { xml << XmlFu::Array.to_xml(@value) }
164
+ else
165
+ # Shouldn't be anything else
166
+ end
167
+ else
168
+ xml.tag!(@name, @attributes) { xml << self.value }
139
169
  end
140
170
  xml.target!
141
171
  end#to_xml
@@ -1,3 +1,3 @@
1
1
  module XmlFu
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
data/lib/xml-fu.rb CHANGED
@@ -5,13 +5,12 @@ require "xml-fu/array"
5
5
  module XmlFu
6
6
  class << self
7
7
 
8
- @@infer_simple_value_nodes = false
9
-
10
8
  # Convert construct into XML
11
9
  def xml(construct, options={})
12
10
  case construct
13
11
  when ::Hash then Hash.to_xml( construct.dup, options )
14
12
  when ::Array then Array.to_xml( construct.dup, options )
13
+ else nil
15
14
  end
16
15
  end#convert
17
16
 
@@ -25,13 +24,19 @@ module XmlFu
25
24
  # an array of one hash (the root node hash)
26
25
  #
27
26
  # <foo><bar/><baz/></foo> => [{"foo" => [{"bar/" => ""},{"baz/" => ""}] }]
28
- def hash(xml, options)
27
+ def parse(xml, options)
29
28
  end
30
29
 
31
30
  def configure
32
31
  yield self
33
32
  end
34
33
 
34
+ ################################################################################
35
+ ## CONFIGURATIONS
36
+ ################################################################################
37
+
38
+ @@infer_simple_value_nodes = false
39
+
35
40
  # Set configuration option to be used with future releases
36
41
  def infer_simple_value_nodes=(val)
37
42
  @@infer_simple_value_nodes = val
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe XmlFu::Array do
4
-
5
4
  describe ".to_xml" do
6
5
  #after do
7
6
  # XmlFu.infer_simple_value_nodes = false
@@ -33,8 +33,10 @@ describe XmlFu::Hash do
33
33
 
34
34
  describe "with a key that will contain multiple nodes" do
35
35
  describe "when key explicitly denotes value is a collection" do
36
- hash = { "foo*" => ["bar", "biz"] }
37
- XmlFu::Hash.to_xml(hash).should == "<foo>bar</foo><foo>biz</foo>"
36
+ it "should return the correct collection" do
37
+ hash = { "foo*" => ["bar", "biz"] }
38
+ XmlFu::Hash.to_xml(hash).should == "<foo>bar</foo><foo>biz</foo>"
39
+ end
38
40
  end
39
41
 
40
42
  describe "when key denotes value contains children" do
@@ -1,6 +1,42 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe XmlFu::Node do
4
+ it "should remove special characters from name no matter how many times they appear at the end" do
5
+ node = XmlFu::Node.new("foo/*!", 'something')
6
+ node.name.should == 'foo'
7
+
8
+ node = XmlFu::Node.new("foo/*/**/!!!", 'something')
9
+ node.name.should == 'foo'
10
+ end
11
+
12
+ describe "with hash as value" do
13
+ it "should store the value as a hash" do
14
+ node = XmlFu::Node.new("foo", {"bar" => "biz"})
15
+ node.value.class.should == Hash
16
+ end
17
+
18
+ it "should create nested nodes with simple hash" do
19
+ node = XmlFu::Node.new("foo", {"bar" => "biz"})
20
+ node.to_xml.should == "<foo><bar>biz</bar></foo>"
21
+ end
22
+ end
23
+
24
+ describe "with array as value" do
25
+ it "should store the value as an array" do
26
+ node = XmlFu::Node.new("foo", ["bar", "biz"])
27
+ node.value.class.should == Array
28
+ end
29
+
30
+ it "should create nodes with simple collection array" do
31
+ node = XmlFu::Node.new("foo*", ["bar", "biz"])
32
+ node.to_xml.should == "<foo>bar</foo><foo>biz</foo>"
33
+ end
34
+
35
+ it "should create nodes with simple contents array" do
36
+ node = XmlFu::Node.new("foo*", [{:bar => "biz"}])
37
+ node.to_xml.should == "<foo><bar>biz</bar></foo>"
38
+ end
39
+ end
4
40
 
5
41
  describe "setting instance variables" do
6
42
  it "should correctly remove special characters from a name" do
@@ -12,6 +48,9 @@ describe XmlFu::Node do
12
48
 
13
49
  node = XmlFu::Node.new("foo!", "something")
14
50
  node.name.should == "foo"
51
+
52
+ node = XmlFu::Node.new("foo:bar!", "something")
53
+ node.name.should == "foo:bar"
15
54
  end
16
55
 
17
56
  it "should set self-closing with special name character" do
@@ -24,6 +63,14 @@ describe XmlFu::Node do
24
63
  node.escape_xml.should == false
25
64
  end
26
65
 
66
+ it "should set content_type with special name character" do
67
+ node = XmlFu::Node.new("foo", "something")
68
+ node.content_type.should == "container"
69
+
70
+ node = XmlFu::Node.new("foo*", "something")
71
+ node.content_type.should == "collection"
72
+ end
73
+
27
74
  it "should set attributes with a hash" do
28
75
  node = XmlFu::Node.new("foo", "bar", {:this => "that"})
29
76
  node.attributes.should == {:this => "that"}
@@ -54,13 +101,14 @@ describe XmlFu::Node do
54
101
  it "should properly preserve namespaceds names" do
55
102
  node = XmlFu::Node.new("foo:bar", "biz")
56
103
  node.name.should == "foo:bar"
104
+
105
+ node = XmlFu::Node.new("foo:bar!", "biz")
106
+ node.name.should == "foo:bar"
57
107
  end
58
108
  end
59
109
 
60
110
  describe "to_xml" do
61
-
62
111
  describe "should return self-closing nil XML node for nil value" do
63
-
64
112
  it "provided ANY non-blank name" do
65
113
  nil_foo = "<foo xsi:nil=\"true\"/>"
66
114
  node = XmlFu::Node.new("foo", nil)
@@ -75,9 +123,12 @@ describe XmlFu::Node do
75
123
 
76
124
  it "with additional attributes provided" do
77
125
  node = XmlFu::Node.new("foo", nil, {:this => "that"})
78
- node.to_xml.should == "<foo this=\"that\" xsi:nil=\"true\"/>"
126
+ # Depending on the version of ruby, one of
127
+ # these two acceptible values would be returned
128
+ [ "<foo this=\"that\" xsi:nil=\"true\"/>",
129
+ "<foo xsi:nil=\"true\" this=\"that\"/>"
130
+ ].should include(node.to_xml)
79
131
  end
80
-
81
132
  end
82
133
 
83
134
  it "should escape values by default" do
@@ -108,5 +159,4 @@ describe XmlFu::Node do
108
159
  end
109
160
  end
110
161
  end
111
-
112
162
  end
data/spec/xmlfu_spec.rb CHANGED
@@ -2,6 +2,12 @@ require 'spec_helper'
2
2
 
3
3
  describe XmlFu do
4
4
  describe ".xml" do
5
+ it "should return nil for value that isn't a Hash or Array" do
6
+ XmlFu.xml(1).should == nil
7
+ XmlFu.xml(nil).should == nil
8
+ XmlFu.xml(Object.new).should == nil
9
+ end
10
+
5
11
  it "translates a given Hash to XML" do
6
12
  XmlFu.xml( :id => 1 ).should == "<id>1</id>"
7
13
  end
@@ -41,6 +47,16 @@ describe XmlFu do
41
47
  XmlFu.xml(hash).should == "<foo bar=\"biz\"></foo><foo biz=\"bang\"></foo>"
42
48
  end
43
49
 
50
+ it "should return list of self-closing nodes" do
51
+ hash = {
52
+ "foo/*" => [
53
+ {"@bar" => "biz"},
54
+ {"@biz" => "bang"}
55
+ ]
56
+ }
57
+ XmlFu.xml(hash).should == "<foo bar=\"biz\"/><foo biz=\"bang\"/>"
58
+ end
59
+
44
60
  it "should ignore nested values for content array" do
45
61
  output = XmlFu.xml("foo/" => [{:bar => "biz"}, {:bar => "biz"}])
46
62
  output.should == "<foo/>"
@@ -53,7 +69,6 @@ describe XmlFu do
53
69
  output = XmlFu.xml("foo/" => {"@id" => "0"})
54
70
  output.should == "<foo id=\"0\"/>"
55
71
  end
56
-
57
72
  end
58
73
 
59
74
  describe "configure" do
@@ -71,5 +86,4 @@ describe XmlFu do
71
86
  XmlFu.infer_simple_value_nodes = false
72
87
  XmlFu.infer_simple_value_nodes.should == false
73
88
  end
74
-
75
89
  end
data/xml-fu.gemspec CHANGED
@@ -19,8 +19,6 @@ Gem::Specification.new do |gem|
19
19
  gem.add_dependency "builder", ">= 2.1.2"
20
20
 
21
21
  gem.add_development_dependency "rspec", ">= 2.4.0"
22
- gem.add_development_dependency "autotest"
23
- gem.add_development_dependency "mocha", "~> 0.9.9"
24
22
 
25
23
  gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
26
24
  gem.files = `git ls-files`.split("\n")
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xml-fu
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 31
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 1
10
- version: 0.1.1
9
+ - 2
10
+ version: 0.1.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ryan Johnson
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-03-13 00:00:00 Z
18
+ date: 2012-03-16 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: builder
@@ -49,36 +49,6 @@ dependencies:
49
49
  version: 2.4.0
50
50
  type: :development
51
51
  version_requirements: *id002
52
- - !ruby/object:Gem::Dependency
53
- name: autotest
54
- prerelease: false
55
- requirement: &id003 !ruby/object:Gem::Requirement
56
- none: false
57
- requirements:
58
- - - ">="
59
- - !ruby/object:Gem::Version
60
- hash: 3
61
- segments:
62
- - 0
63
- version: "0"
64
- type: :development
65
- version_requirements: *id003
66
- - !ruby/object:Gem::Dependency
67
- name: mocha
68
- prerelease: false
69
- requirement: &id004 !ruby/object:Gem::Requirement
70
- none: false
71
- requirements:
72
- - - ~>
73
- - !ruby/object:Gem::Version
74
- hash: 41
75
- segments:
76
- - 0
77
- - 9
78
- - 9
79
- version: 0.9.9
80
- type: :development
81
- version_requirements: *id004
82
52
  description: "\n Inspired by the Gyoku gem for hash to xml conversion, \n XmlFu is designed to require no meta tagging for \n node attributes and content. (i.e. no :attributes! and no :order!)\n "
83
53
  email:
84
54
  - rhino.citguy@gmail.com