xml-fu 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -2,6 +2,7 @@
2
2
  *.rbc
3
3
  *.swp
4
4
  .rvmrc
5
+ .ruby-*
5
6
  .bundle
6
7
  .config
7
8
  .yardoc
@@ -1,5 +1,15 @@
1
1
  ## Changes by Version
2
2
 
3
+ ### 0.1.8
4
+
5
+ * Fixed XmlFu.symbol_conversion_algorithm functionality
6
+ * Added specs for above
7
+ * Removed :snake_case algorithm
8
+ ** It never worked and can be implemented via a custom algorithm.
9
+ * Added :upcase algorithm
10
+ * Added :downcase algorithm
11
+ * Updated README
12
+
3
13
  ### 0.1.7
4
14
 
5
15
  * Added pass through for Builder::XmlMarkup options via XmlFu.xml
@@ -41,9 +51,9 @@
41
51
 
42
52
  ### 0.1.0
43
53
 
44
- * Initial version. born as a replacement of
54
+ * Initial version. born as a replacement of
45
55
  [Gyoku](http://www.rubygems.org/gems/gyoku)
46
56
  with corrected assumptions about Array values and
47
57
  no need for meta tags such as:
48
- * :order!
58
+ * :order!
49
59
  * :attributes!
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Convert Ruby Hashes to XML
4
4
 
5
- A hash is meant to be a structured set of data. So is XML. The two are very similar in that they have
5
+ A hash is meant to be a structured set of data. So is XML. The two are very similar in that they have
6
6
  the capability of nesting information within a tree structure. With XML you have nodes. With Hashes, you
7
7
  have key/value pairs. The value of an XML node is referenced by its parent's name. A hash value is referenced
8
8
  by its key. This basic lesson tells the majority of what you need to know about creating XML via Hashes in
@@ -29,30 +29,53 @@ Or install it yourself as:
29
29
  Hash keys are translated into XML nodes (whether it be a document node or attribute node).
30
30
 
31
31
 
32
- ### Translation
32
+ ### Key Translation
33
33
 
34
- With Ruby, a hash key may be a string or a symbol. XmlFu will convert the symbols into an XML safe name
35
- by lower camel-casing them. So :foo\_bar will become "fooBar". You may change the conversion algorithm to your
36
- liking by setting the XmlFu.symbol\_conversion\_algorithm to a lambda or proc of your liking.
34
+ With Ruby, a hash key may be a string or a symbol. **Strings will be preserved** as they may
35
+ contain node namespacing ("foo:Bar" would need preserved rather than converted). Symbols will
36
+ be converted into an XML safe name by lower camel-casing them. So :foo\_bar will become "fooBar".
37
+ You may change the conversion algorithm to your liking by setting the
38
+ XmlFu.symbol\_conversion\_algorithm to a lambda or proc of your liking.
37
39
 
38
40
 
39
41
  #### Built-In Algorithms
40
42
 
41
- * :lower\_camelcase **(default)**
43
+ For a complete list, reference XmlFu::Node::ALGORITHMS
44
+
42
45
  * :camelcase
46
+ * :downcase
47
+ * :lower\_camelcase **(default)**
43
48
  * :none (result of :sym.to\_s)
44
- * :snake\_case (alias for :none)
49
+ * :upcase
45
50
 
46
51
  ```ruby
47
- # Built-in Algorithm
48
- XmlFu.symbol_conversion_algorithm(:camelcase)
52
+ # Default Algorithm (:lower_camelcase)
53
+ XmlFu.xml( :FooBar => "bang" ) #=> "<fooBar>bang</fooBar>"
54
+ XmlFu.xml( :foo_bar => "bang" ) #=> "<fooBar>bang</fooBar>"
55
+
56
+
57
+ # Built-in Algorithms (:camelcase)
58
+ XmlFu.symbol_conversion_algorithm = :camelcase
59
+ XmlFu.xml( :Foo_Bar => "bang" ) #=> "<FooBar>bang</FooBar>"
60
+ XmlFu.xml( :foo_bar => "bang" ) #=> "<FooBar>bang</FooBar>"
61
+
62
+
63
+ # Built-in Algorithms (:downcase)
64
+ XmlFu.symbol_conversion_algorithm = :downcase
65
+ XmlFu.xml( :foo_bar => "bang" ) #=> "<foo_bar>bang</foo_bar>"
66
+ XmlFu.xml( :Foo_Bar => "bang" ) #=> "<foo_bar>bang</foo_bar>"
67
+ XmlFu.xml( :FOO => "bar" ) #=> "<foo>bar</foo>"
68
+
69
+
70
+ # Built-in Algorithms (:upcase)
71
+ XmlFu.symbol_conversion_algorithm = :upcase
72
+ XmlFu.xml( :foo_bar => "bang" ) #=> "<FOO_BAR>bang</FOO_BAR>"
73
+ XmlFu.xml( :Foo_Bar => "bang" ) #=> "<FOO_BAR>bang</FOO_BAR>"
74
+ XmlFu.xml( :foo => "bar" ) #=> "<FOO>bar</FOO>"
49
75
 
50
- XmlFu.xml( :foo => "bar" ) #=> "<foo>bar</foo>"
51
- XmlFu.xml( "foo" => "bar" ) #=> "<foo>bar</foo>"
52
- # :foo and "foo" both translate to <foo>
53
76
 
54
77
  # Custom Algorithm
55
- XmlFu.symbol_conversion_algorithm {|sym| sym.downcase }
78
+ XmlFu.symbol_conversion_algorithm = lambda {|sym| sym.do_something_special }
56
79
  ```
57
80
 
58
81
  ### Types of Nodes
@@ -91,14 +114,14 @@ XmlFu.xml("foo!" => "<bar/>") #=> "<foo><bar/></foo>"
91
114
 
92
115
  #### Attribute Node (@key)
93
116
 
94
- Yes, the attributes of an XML node are nodes themselves, so we need a way of defining them. Since XPath syntax
117
+ Yes, the attributes of an XML node are nodes themselves, so we need a way of defining them. Since XPath syntax
95
118
  uses @ to denote an attribute, so does XmlFu.
96
119
 
97
120
  ``` ruby
98
- XmlFu.xml(:agent => {
99
- "@id" => "007",
100
- "FirstName" => "James",
101
- "LastName" => "Bond"
121
+ XmlFu.xml(:agent => {
122
+ "@id" => "007",
123
+ "FirstName" => "James",
124
+ "LastName" => "Bond"
102
125
  })
103
126
  #=> <agent id="007"><FirstName>James</FirstName><LastName>Bond</LastName></agent>
104
127
  ```
@@ -156,7 +179,7 @@ XmlFu.xml(:agent => {"@id" => "007", "=" => "James Bond"})
156
179
  #=> "<agent id=\"007\">James Bond</agent>"
157
180
  ```
158
181
 
159
- This key will not get around the self-closing node rule. The only nodes that will be used in this case will be
182
+ This key will not get around the self-closing node rule. The only nodes that will be used in this case will be
160
183
  attribute nodes and additional content will be ignored.
161
184
 
162
185
  ```ruby
@@ -167,7 +190,7 @@ XmlFu.xml("foo/" => {"@id" => "123", "=" => "You can't see me."})
167
190
 
168
191
  ### Arrays
169
192
 
170
- Since the value in a key/value pair is (for the most part) used as the contents of a key/node, there are some
193
+ Since the value in a key/value pair is (for the most part) used as the contents of a key/node, there are some
171
194
  assumptions that XmlFu makes when dealing with Array values.
172
195
 
173
196
  * For a typical key, the contents of the array are considered to be nodes to be contained within the <key> node.
@@ -177,7 +200,7 @@ assumptions that XmlFu makes when dealing with Array values.
177
200
 
178
201
  ``` ruby
179
202
  XmlFu.xml( "SecretAgents" => [
180
- { "agent/" => { "@id"=>"006", "@name"=>"Alec Trevelyan" } },
203
+ { "agent/" => { "@id"=>"006", "@name"=>"Alec Trevelyan" } },
181
204
  { "agent/" => { "@id"=>"007", "@name"=>"James Bond" } }
182
205
  ])
183
206
  #=> "<SecretAgents><agent name=\"Alec Trevelyan\" id=\"006\"/><agent name=\"James Bond\" id=\"007\"/></SecretAgents>"
@@ -202,12 +225,12 @@ How about a more complex example:
202
225
 
203
226
  ```ruby
204
227
  XmlFu.xml(
205
- "person*" => {
206
- "@foo" => "bar",
228
+ "person*" => {
229
+ "@foo" => "bar",
207
230
  "=" => [
208
- {"@foo" => "nope", "=" => "Bob"},
231
+ {"@foo" => "nope", "=" => "Bob"},
209
232
  "Sheila"
210
- ]
233
+ ]
211
234
  }
212
235
  )
213
236
  #=> "<person foo=\"nope\">Bob</person><person foo=\"bar\">Sheila</person>"
@@ -268,7 +291,7 @@ are currently ignored in arrays and only Hashes are translated.
268
291
  1. if key denotes self-closing node (key/)
269
292
  * attributes are preserved with Hash values
270
293
  * value and "=" values are ignored
271
- 2. if key denotes collection (key*) with Array value
294
+ 2. if key denotes collection (key*) with Array value
272
295
  * Array is flattened
273
296
  * Only Hash and Simple values are translated
274
297
  * Hashes may override default attributes set by parent
@@ -5,7 +5,7 @@ require "xml-fu/markup"
5
5
 
6
6
  module XmlFu
7
7
  class << self
8
-
8
+
9
9
  # Convert construct into XML
10
10
  def xml(construct, options={})
11
11
  case construct
@@ -16,7 +16,7 @@ module XmlFu
16
16
  end#convert
17
17
 
18
18
  # @todo Add Nori-like parsing capability to convert XML back into XmlFu-compatible Hash/Array
19
- # Parse XML into array of hashes. If XML used as input contains only sibling nodes, output
19
+ # Parse XML into array of hashes. If XML used as input contains only sibling nodes, output
20
20
  # will be array of hashes corresponding to those sibling nodes.
21
21
  #
22
22
  # <foo/><bar/> => [{"foo/" => ""}, {"bar/" => ""}]
@@ -38,7 +38,7 @@ module XmlFu
38
38
  ################################################################################
39
39
  ## CONFIGURATIONS
40
40
  ################################################################################
41
-
41
+
42
42
  @@infer_simple_value_nodes = false
43
43
 
44
44
  # Set configuration option to be used with future releases
@@ -58,5 +58,18 @@ module XmlFu
58
58
  return @@infer_simple_value_nodes
59
59
  end
60
60
 
61
+
62
+ # @param formula_enum Formula Enumeration
63
+ # @return [lambda]
64
+ def symbol_conversion_algorithm=( formula_enum=nil, &block )
65
+ XmlFu::Node.symbol_conversion_algorithm = (formula_enum ? formula_enum : block)
66
+ end#symbol_conversion_algorithm
67
+
68
+
69
+ # @return [lambda]
70
+ def symbol_conversion_algorithm
71
+ XmlFu::Node.symbol_conversion_algorithm
72
+ end#symbol_conversion_algorithm
73
+
61
74
  end#class<<self
62
75
  end#XmlFu
@@ -9,57 +9,61 @@ module XmlFu
9
9
  # If order is of concern, use Array.to_xml
10
10
  class Hash
11
11
 
12
- # Convert Hash to XML String
13
- def self.to_xml(hash, options={})
14
- each_with_xml hash, options do |xml, name, value, attributes|
15
- xml << Node.new(name, value, attributes).to_xml
16
- end
17
- end#self.to_xml
12
+ class << self
18
13
 
14
+ # Convert Hash to XML String
15
+ def to_xml(hash, options={})
16
+ each_with_xml hash, options do |xml, name, value, attributes|
17
+ xml << Node.new(name, value, attributes).to_xml
18
+ end
19
+ end#to_xml
19
20
 
20
- # Class method to filter out attributes and content
21
- # from a given hash
22
- def self.filter(hash)
23
- attribs = {}
24
- content = hash.dup
25
21
 
26
- content.keys.select{|k| k =~ /^@/ }.each do |k|
27
- attribs[k[1..-1]] = content.delete(k)
28
- end
22
+ # Class method to filter out attributes and content
23
+ # from a given hash
24
+ def filter(hash)
25
+ attribs = {}
26
+ content = hash.dup
29
27
 
30
- # Use _content value if defined
31
- content = content.delete("=") || content
28
+ content.keys.select{|k| k =~ /^@/ }.each do |k|
29
+ attribs[k[1..-1]] = content.delete(k)
30
+ end
32
31
 
33
- return [content, attribs]
34
- end#self.filter
32
+ # Use _content value if defined
33
+ content = content.delete("=") || content
35
34
 
36
- private
35
+ return [content, attribs]
36
+ end#filter
37
37
 
38
- # Provides a convenience function to iterate over the hash
39
- # Logic will filter out attribute and content keys from hash values
40
- def self.each_with_xml(hash, opts={})
41
- xml = XmlFu::Markup.new(opts)
38
+ private
42
39
 
43
- hash.each do |key,value|
44
- node_value = value
45
- node_attrs = {}
40
+ # Provides a convenience function to iterate over the hash
41
+ # Logic will filter out attribute and content keys from hash values
42
+ def each_with_xml(hash, opts={})
43
+ xml = XmlFu::Markup.new(opts)
46
44
 
47
- # yank the attribute keys into their own hash
48
- if value.respond_to?(:keys)
49
- filtered = Hash.filter(value)
50
- node_value, node_attrs = filtered.first, filtered.last
51
- end
45
+ hash.each do |key,value|
46
+ node_value = value
47
+ node_attrs = {}
52
48
 
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 )
49
+ # yank the attribute keys into their own hash
50
+ if value.respond_to?(:keys)
51
+ filtered = Hash.filter(value)
52
+ node_value, node_attrs = filtered.first, filtered.last
53
+ end
54
+
55
+ # Use symbol conversion algorithm to set tag name
56
+ node_name = ( Symbol === key ?
57
+ XmlFu::Node.symbol_conversion_algorithm.call(key) :
58
+ key.to_s )
59
+
60
+ yield xml, node_name, node_value, node_attrs
61
+ end
57
62
 
58
- yield xml, node_name, node_value, node_attrs
59
- end
63
+ xml.target!
64
+ end#each_with_xml
60
65
 
61
- xml.target!
62
- end#self.each_with_xml
66
+ end#class << self
63
67
 
64
68
  end#Hash
65
69
 
@@ -17,10 +17,11 @@ module XmlFu
17
17
 
18
18
  # default set of algorithms to choose from
19
19
  ALGORITHMS = {
20
- :lower_camelcase => lambda { |sym| sym.to_s.lower_camelcase },
21
20
  :camelcase => lambda { |sym| sym.to_s.camelcase },
22
- :snakecase => lambda { |sym| sym.to_s },
23
- :none => lambda { |sym| sym.to_s }
21
+ :downcase => lambda { |sym| sym.to_s.downcase },
22
+ :lower_camelcase => lambda { |sym| sym.to_s.lower_camelcase }, # DEFAULT
23
+ :none => lambda { |sym| sym.to_s },
24
+ :upcase => lambda { |sym| sym.to_s.upcase }
24
25
  }
25
26
 
26
27
  # Class method for retrieving global Symbol-to-string conversion algorithm
@@ -30,9 +31,15 @@ module XmlFu
30
31
  end#self.symbol_conversion_algorithm
31
32
 
32
33
  # Class method for setting global Symbol-to-string conversion algorithm
33
- # @param [lambda] algorithm Should accept a symbol as an argument and return a string
34
+ # @param [symbol, lambda] algorithm
35
+ # Can be symbol corresponding to predefined algorithm or a lambda that accepts a symbol
36
+ # as an argument and returns a string
34
37
  def self.symbol_conversion_algorithm=(algorithm)
35
- algorithm = ALGORITHMS[algorithm] unless algorithm.respond_to?(:call)
38
+ if algorithm == :default
39
+ algorithm = ALGORITHMS[:lower_camelcase]
40
+ else
41
+ algorithm = ALGORITHMS[algorithm] unless algorithm.respond_to?(:call)
42
+ end
36
43
  raise(ArgumentError, "Invalid symbol conversion algorithm") unless algorithm
37
44
  @symbol_conversion_algorithm = algorithm
38
45
  end#self.symbol_conversion_algorithm=
@@ -69,8 +76,6 @@ module XmlFu
69
76
 
70
77
  use_name = name_parse_special_characters(use_name)
71
78
 
72
- # TODO: Add additional logic that Gyoku XmlKey puts in place
73
-
74
79
  # remove ":" if name begins with ":" (i.e. no namespace)
75
80
  use_name = use_name[1..-1] if use_name[0,1] == ":"
76
81
 
@@ -97,7 +102,7 @@ module XmlFu
97
102
 
98
103
  # Will this be a self closing node?
99
104
  if use_this.to_s[-1,1] == '/'
100
- @self_closing = true
105
+ @self_closing = true
101
106
  use_this.chop!
102
107
  end
103
108
 
@@ -148,14 +153,14 @@ module XmlFu
148
153
  case
149
154
  when @self_closing && @content_type == 'container'
150
155
  xml.tag!(@name, @attributes)
151
- when @value.nil?
156
+ when @value.nil?
152
157
  xml.tag!(@name, @attributes.merge!("xsi:nil" => "true"))
153
158
  when ::Hash === @value
154
159
  xml.tag!(@name, @attributes) { xml << XmlFu::Hash.to_xml(@value) }
155
160
  when ::Array === @value
156
161
  case @content_type
157
162
  when "collection"
158
- xml << XmlFu::Array.to_xml(@value.flatten, {
163
+ xml << XmlFu::Array.to_xml(@value.flatten, {
159
164
  :key => (@self_closing ? "#{@name}/" : @name),
160
165
  :attributes => @attributes,
161
166
  :content_type => "collection"
@@ -1,3 +1,3 @@
1
1
  module XmlFu
2
- VERSION = "0.1.7"
2
+ VERSION = "0.1.8"
3
3
  end
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ describe XmlFu do
4
+ after(:each) do
5
+ XmlFu.symbol_conversion_algorithm = :default
6
+ end
7
+
8
+ describe "with default symbol conversion algorithm" do
9
+ before(:each) do
10
+ XmlFu.symbol_conversion_algorithm = :default
11
+ end
12
+
13
+ {
14
+ :FooBar => "fooBar",
15
+ :foobar => "foobar"
16
+ }.each do |k,v|
17
+ it "should convert :#{k} to #{v}" do
18
+ doc = XmlFu.xml( k => "")
19
+ doc.should == "<#{v}></#{v}>"
20
+ end
21
+ end
22
+ end#default (:lower_camelcase)
23
+
24
+
25
+ describe "with built-in :camelcase algorithm" do
26
+ before(:each) do
27
+ XmlFu.symbol_conversion_algorithm = :camelcase
28
+ end
29
+
30
+ {
31
+ :foo_bar => "FooBar",
32
+ :foobar => "Foobar"
33
+ }.each do |k,v|
34
+ it "should convert :#{k} to #{v}" do
35
+ doc = XmlFu.xml( k => "")
36
+ doc.should == "<#{v}></#{v}>"
37
+ end
38
+ end
39
+ end#:camelcase
40
+
41
+
42
+ describe "with built-in :downcase algorithm" do
43
+ before(:each) do
44
+ XmlFu.symbol_conversion_algorithm = :downcase
45
+ end
46
+
47
+ {
48
+ :FOO_BAR => "foo_bar",
49
+ :FooBar => "foobar"
50
+ }.each do |k,v|
51
+ it "should convert :#{k} to #{v}" do
52
+ doc = XmlFu.xml( k => "")
53
+ doc.should == "<#{v}></#{v}>"
54
+ end
55
+ end
56
+ end#:downcase
57
+
58
+
59
+ describe "with built-in :upcase algorithm" do
60
+ before(:each) do
61
+ XmlFu.symbol_conversion_algorithm = :upcase
62
+ end
63
+
64
+ {
65
+ :foo_bar => "FOO_BAR",
66
+ :FooBar => "FOOBAR"
67
+ }.each do |k,v|
68
+ it "should convert :#{k} to #{v}" do
69
+ doc = XmlFu.xml( k => "")
70
+ doc.should == "<#{v}></#{v}>"
71
+ end
72
+ end
73
+ end#:upcase
74
+
75
+ end
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: 21
4
+ hash: 11
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 7
10
- version: 0.1.7
9
+ - 8
10
+ version: 0.1.8
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-21 00:00:00 Z
18
+ date: 2013-07-22 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: builder
@@ -91,6 +91,7 @@ files:
91
91
  - spec/lib/array_spec.rb
92
92
  - spec/lib/hash_spec.rb
93
93
  - spec/lib/node_spec.rb
94
+ - spec/lib/xml-fu_spec.rb
94
95
  - spec/lib/xml_spec.rb
95
96
  - spec/spec_helper.rb
96
97
  - spec/xmlfu_spec.rb
@@ -124,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
124
125
  requirements: []
125
126
 
126
127
  rubyforge_project: xml-fu
127
- rubygems_version: 1.8.10
128
+ rubygems_version: 1.8.24
128
129
  signing_key:
129
130
  specification_version: 3
130
131
  summary: Simple Hash/Array to XML generation
@@ -132,6 +133,7 @@ test_files:
132
133
  - spec/lib/array_spec.rb
133
134
  - spec/lib/hash_spec.rb
134
135
  - spec/lib/node_spec.rb
136
+ - spec/lib/xml-fu_spec.rb
135
137
  - spec/lib/xml_spec.rb
136
138
  - spec/spec_helper.rb
137
139
  - spec/xmlfu_spec.rb