nori 2.3.0 → 2.4.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.
- data/.travis.yml +1 -5
- data/CHANGELOG.md +8 -0
- data/Gemfile +7 -0
- data/README.md +18 -0
- data/lib/nori.rb +9 -2
- data/lib/nori/core_ext/hash.rb +27 -22
- data/lib/nori/core_ext/string.rb +3 -3
- data/lib/nori/version.rb +1 -3
- data/lib/nori/xml_utility_node.rb +9 -3
- data/nori.gemspec +1 -1
- data/spec/nori/api_spec.rb +8 -0
- data/spec/nori/nori_spec.rb +21 -11
- metadata +17 -15
- checksums.yaml +0 -7
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
# 2.4.0 (2014-04-19)
|
2
|
+
|
3
|
+
* Change: Dropped support for ruby 1.8, rubinius and ree
|
4
|
+
|
5
|
+
* Feature: Added `:convert_attributes` feature similar to `:convert_tags_to`
|
6
|
+
|
7
|
+
* Feature: Added `:convert_dashes_to_underscore` option
|
8
|
+
|
1
9
|
# 2.3.0 (2013-07-26)
|
2
10
|
|
3
11
|
* Change: `Nori#find` now ignores namespace prefixes in Hash keys it is searching through.
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -67,3 +67,21 @@ parser = Nori.new(:convert_tags_to => lambda { |tag| tag.snakecase.to_sym })
|
|
67
67
|
xml = '<userResponse><accountStatus>active</accountStatus></userResponse>'
|
68
68
|
parser.parse(xml) # => { :user_response => { :account_status => "active" }
|
69
69
|
```
|
70
|
+
|
71
|
+
Dashes and underscores
|
72
|
+
----------------------
|
73
|
+
|
74
|
+
Nori will automatically convert dashes in tag names to underscores.
|
75
|
+
For example:
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
parser = Nori.new
|
79
|
+
parser.parse('<any-tag>foo bar</any-tag>') # => { "any_tag" => "foo bar" }
|
80
|
+
```
|
81
|
+
|
82
|
+
You can control this behavior with the `:convert_dashes_to_underscores` option:
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
parser = Nori.new(:convert_dashes_to_underscores => false)
|
86
|
+
parser.parse('<any-tag>foo bar</any-tag>') # => { "any-tag" => "foo bar" }
|
87
|
+
```
|
data/lib/nori.rb
CHANGED
@@ -5,7 +5,7 @@ require "nori/xml_utility_node"
|
|
5
5
|
class Nori
|
6
6
|
|
7
7
|
def self.hash_key(name, options = {})
|
8
|
-
name = name.tr("-", "_")
|
8
|
+
name = name.tr("-", "_") if options[:convert_dashes_to_underscores]
|
9
9
|
name = name.split(":").last if options[:strip_namespaces]
|
10
10
|
name = options[:convert_tags_to].call(name) if options[:convert_tags_to].respond_to? :call
|
11
11
|
name
|
@@ -18,7 +18,9 @@ class Nori
|
|
18
18
|
:strip_namespaces => false,
|
19
19
|
:delete_namespace_attributes => false,
|
20
20
|
:convert_tags_to => nil,
|
21
|
+
:convert_attributes_to => nil,
|
21
22
|
:advanced_typecasting => true,
|
23
|
+
:convert_dashes_to_underscores => true,
|
22
24
|
:parser => :nokogiri
|
23
25
|
}
|
24
26
|
|
@@ -45,12 +47,17 @@ class Nori
|
|
45
47
|
end
|
46
48
|
|
47
49
|
private
|
48
|
-
|
49
50
|
def load_parser(parser)
|
50
51
|
require "nori/parser/#{parser}"
|
51
52
|
Parser.const_get PARSERS[parser]
|
52
53
|
end
|
53
54
|
|
55
|
+
# Expects a +block+ which receives a tag to convert.
|
56
|
+
# Accepts +nil+ for a reset to the default behavior of not converting tags.
|
57
|
+
def convert_tags_to(reset = nil, &block)
|
58
|
+
@convert_tag = reset || block
|
59
|
+
end
|
60
|
+
|
54
61
|
def validate_options!(available_options, options)
|
55
62
|
spurious_options = options - available_options
|
56
63
|
|
data/lib/nori/core_ext/hash.rb
CHANGED
@@ -16,9 +16,7 @@ class Nori
|
|
16
16
|
# }.to_params
|
17
17
|
# #=> "name=Bob&address[city]=Ruby Central&address[phones][]=111-111-1111&address[phones][]=222-222-2222&address[street]=111 Ruby Ave."
|
18
18
|
def to_params
|
19
|
-
|
20
|
-
params.chop! # trailing &
|
21
|
-
params
|
19
|
+
map { |k, v| normalize_param(k,v) }.flatten.join('&')
|
22
20
|
end
|
23
21
|
|
24
22
|
# @param key<Object> The key for the param.
|
@@ -26,30 +24,15 @@ class Nori
|
|
26
24
|
#
|
27
25
|
# @return <String> This key value pair as a param
|
28
26
|
#
|
29
|
-
# @example normalize_param(:name, "Bob Jones") #=> "name=Bob%20Jones
|
27
|
+
# @example normalize_param(:name, "Bob Jones") #=> "name=Bob%20Jones"
|
30
28
|
def normalize_param(key, value)
|
31
|
-
param = ''
|
32
|
-
stack = []
|
33
|
-
|
34
29
|
if value.is_a?(Array)
|
35
|
-
|
30
|
+
normalize_array_params(key, value)
|
36
31
|
elsif value.is_a?(Hash)
|
37
|
-
|
32
|
+
normalize_hash_params(key, value)
|
38
33
|
else
|
39
|
-
|
40
|
-
end
|
41
|
-
|
42
|
-
stack.each do |parent, hash|
|
43
|
-
hash.each do |key, value|
|
44
|
-
if value.is_a?(Hash)
|
45
|
-
stack << ["#{parent}[#{key}]", value]
|
46
|
-
else
|
47
|
-
param << normalize_param("#{parent}[#{key}]", value)
|
48
|
-
end
|
49
|
-
end
|
34
|
+
normalize_simple_type_params(key, value)
|
50
35
|
end
|
51
|
-
|
52
|
-
param
|
53
36
|
end
|
54
37
|
|
55
38
|
# @return <String> The hash as attributes for an XML tag.
|
@@ -63,6 +46,28 @@ class Nori
|
|
63
46
|
end.join(' ')
|
64
47
|
end
|
65
48
|
|
49
|
+
private
|
50
|
+
|
51
|
+
def normalize_simple_type_params(key, value)
|
52
|
+
["#{key}=#{encode_simple_value(value)}"]
|
53
|
+
end
|
54
|
+
|
55
|
+
def normalize_array_params(key, array)
|
56
|
+
array.map do |element|
|
57
|
+
normalize_param("#{key}[]", element)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def normalize_hash_params(key, hash)
|
62
|
+
hash.map do |nested_key, element|
|
63
|
+
normalize_param("#{key}[#{nested_key}]", element)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def encode_simple_value(value)
|
68
|
+
URI.encode(value.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
|
69
|
+
end
|
70
|
+
|
66
71
|
end
|
67
72
|
end
|
68
73
|
end
|
data/lib/nori/core_ext/string.rb
CHANGED
@@ -5,9 +5,9 @@ class Nori
|
|
5
5
|
# Returns the String in snake_case.
|
6
6
|
def snakecase
|
7
7
|
str = dup
|
8
|
-
str.gsub!
|
9
|
-
str.gsub!
|
10
|
-
str.gsub!
|
8
|
+
str.gsub!(/::/, '/')
|
9
|
+
str.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
10
|
+
str.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
11
11
|
str.tr! ".", "_"
|
12
12
|
str.tr! "-", "_"
|
13
13
|
str.downcase!
|
data/lib/nori/version.rb
CHANGED
@@ -85,6 +85,11 @@ class Nori
|
|
85
85
|
@options = options
|
86
86
|
@name = Nori.hash_key(name, options)
|
87
87
|
|
88
|
+
if converter = options[:convert_attributes_to]
|
89
|
+
intermediate = attributes.map {|k, v| converter.call(k, v) }.flatten
|
90
|
+
attributes = Hash[*intermediate]
|
91
|
+
end
|
92
|
+
|
88
93
|
# leave the type alone if we don't know what it is
|
89
94
|
@type = self.class.available_typecasts.include?(attributes["type"]) ? attributes.delete("type") : attributes["type"]
|
90
95
|
|
@@ -238,16 +243,17 @@ class Nori
|
|
238
243
|
attributes.merge!(:type => @type ) if @type
|
239
244
|
"<#{name}#{attributes.to_xml_attributes}>#{@nil_element ? '' : inner_html}</#{name}>"
|
240
245
|
end
|
241
|
-
|
242
246
|
alias to_s to_html
|
243
247
|
|
244
248
|
private
|
245
|
-
|
246
249
|
def try_to_convert(value, &block)
|
247
250
|
block.call(value)
|
248
251
|
rescue ArgumentError
|
249
252
|
value
|
250
253
|
end
|
251
|
-
end
|
252
254
|
|
255
|
+
def strip_namespace(string)
|
256
|
+
string.split(":").last
|
257
|
+
end
|
258
|
+
end
|
253
259
|
end
|
data/nori.gemspec
CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.license = "MIT"
|
16
16
|
|
17
17
|
s.add_development_dependency "rake", "~> 10.0"
|
18
|
-
s.add_development_dependency "nokogiri", ">= 1.4.0"
|
18
|
+
s.add_development_dependency "nokogiri", ">= 1.4.0"
|
19
19
|
s.add_development_dependency "rspec", "~> 2.12"
|
20
20
|
|
21
21
|
s.files = `git ls-files`.split("\n")
|
data/spec/nori/api_spec.rb
CHANGED
@@ -162,6 +162,14 @@ describe Nori do
|
|
162
162
|
end
|
163
163
|
end
|
164
164
|
|
165
|
+
context "#parse with :convert_dashes_to_underscores" do
|
166
|
+
it "can be configured to skip dash to underscope conversion" do
|
167
|
+
xml = '<any-tag>foo bar</any-tag'
|
168
|
+
hash = nori(:convert_dashes_to_underscores => false).parse(xml)
|
169
|
+
hash.should == {'any-tag' => 'foo bar'}
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
165
173
|
def nori(options = {})
|
166
174
|
Nori.new(options)
|
167
175
|
end
|
data/spec/nori/nori_spec.rb
CHANGED
@@ -460,6 +460,17 @@ describe Nori do
|
|
460
460
|
end
|
461
461
|
end
|
462
462
|
|
463
|
+
context "with convert_attributes_to set to a custom formula" do
|
464
|
+
it "alters attributes and values" do
|
465
|
+
converter = lambda {|key, value| ["#{key}_k", "#{value}_v"] }
|
466
|
+
xml = <<-XML
|
467
|
+
<user name="value"><age>21</age></user>
|
468
|
+
XML
|
469
|
+
|
470
|
+
parse(xml, :convert_attributes_to => converter).should == {'user' => {'@name_k' => 'value_v', 'age' => '21'}}
|
471
|
+
end
|
472
|
+
end
|
473
|
+
|
463
474
|
it "should handle a single record from_xml with attributes other than type (ActiveSupport Compatible)" do
|
464
475
|
topic_xml = <<-EOT
|
465
476
|
<rsp stat="ok">
|
@@ -600,15 +611,15 @@ describe Nori do
|
|
600
611
|
parse(product_xml)["product"].should == expected_product_hash
|
601
612
|
end
|
602
613
|
|
603
|
-
it "should handle unescaping from xml (ActiveResource Compatible)"
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
614
|
+
it "should handle unescaping from xml (ActiveResource Compatible)" do
|
615
|
+
xml_string = '<person><bare-string>First & Last Name</bare-string><pre-escaped-string>First &amp; Last Name</pre-escaped-string></person>'
|
616
|
+
expected_hash = {
|
617
|
+
'bare_string' => 'First & Last Name',
|
618
|
+
'pre_escaped_string' => 'First & Last Name'
|
619
|
+
}
|
620
|
+
|
621
|
+
parse(xml_string)['person'].should == expected_hash
|
622
|
+
end
|
612
623
|
|
613
624
|
it "handle an empty xml string" do
|
614
625
|
parse('').should == {}
|
@@ -623,8 +634,7 @@ describe Nori do
|
|
623
634
|
end
|
624
635
|
|
625
636
|
def parse(xml, options = {})
|
626
|
-
defaults = {
|
637
|
+
defaults = {:parser => parser}
|
627
638
|
Nori.new(defaults.merge(options)).parse(xml)
|
628
639
|
end
|
629
|
-
|
630
640
|
end
|
metadata
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nori
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.0
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Daniel Harrington
|
@@ -10,11 +11,12 @@ authors:
|
|
10
11
|
autorequire:
|
11
12
|
bindir: bin
|
12
13
|
cert_chain: []
|
13
|
-
date:
|
14
|
+
date: 2014-04-19 00:00:00.000000000 Z
|
14
15
|
dependencies:
|
15
16
|
- !ruby/object:Gem::Dependency
|
16
17
|
name: rake
|
17
18
|
requirement: !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
18
20
|
requirements:
|
19
21
|
- - ~>
|
20
22
|
- !ruby/object:Gem::Version
|
@@ -22,6 +24,7 @@ dependencies:
|
|
22
24
|
type: :development
|
23
25
|
prerelease: false
|
24
26
|
version_requirements: !ruby/object:Gem::Requirement
|
27
|
+
none: false
|
25
28
|
requirements:
|
26
29
|
- - ~>
|
27
30
|
- !ruby/object:Gem::Version
|
@@ -29,26 +32,23 @@ dependencies:
|
|
29
32
|
- !ruby/object:Gem::Dependency
|
30
33
|
name: nokogiri
|
31
34
|
requirement: !ruby/object:Gem::Requirement
|
35
|
+
none: false
|
32
36
|
requirements:
|
33
|
-
- - '>='
|
37
|
+
- - ! '>='
|
34
38
|
- !ruby/object:Gem::Version
|
35
39
|
version: 1.4.0
|
36
|
-
- - <
|
37
|
-
- !ruby/object:Gem::Version
|
38
|
-
version: '1.6'
|
39
40
|
type: :development
|
40
41
|
prerelease: false
|
41
42
|
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
42
44
|
requirements:
|
43
|
-
- - '>='
|
45
|
+
- - ! '>='
|
44
46
|
- !ruby/object:Gem::Version
|
45
47
|
version: 1.4.0
|
46
|
-
- - <
|
47
|
-
- !ruby/object:Gem::Version
|
48
|
-
version: '1.6'
|
49
48
|
- !ruby/object:Gem::Dependency
|
50
49
|
name: rspec
|
51
50
|
requirement: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
52
|
requirements:
|
53
53
|
- - ~>
|
54
54
|
- !ruby/object:Gem::Version
|
@@ -56,6 +56,7 @@ dependencies:
|
|
56
56
|
type: :development
|
57
57
|
prerelease: false
|
58
58
|
version_requirements: !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
59
60
|
requirements:
|
60
61
|
- - ~>
|
61
62
|
- !ruby/object:Gem::Version
|
@@ -97,26 +98,27 @@ files:
|
|
97
98
|
homepage: https://github.com/savonrb/nori
|
98
99
|
licenses:
|
99
100
|
- MIT
|
100
|
-
metadata: {}
|
101
101
|
post_install_message:
|
102
102
|
rdoc_options: []
|
103
103
|
require_paths:
|
104
104
|
- lib
|
105
105
|
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
106
107
|
requirements:
|
107
|
-
- - '>='
|
108
|
+
- - ! '>='
|
108
109
|
- !ruby/object:Gem::Version
|
109
110
|
version: '0'
|
110
111
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
|
+
none: false
|
111
113
|
requirements:
|
112
|
-
- - '>='
|
114
|
+
- - ! '>='
|
113
115
|
- !ruby/object:Gem::Version
|
114
116
|
version: '0'
|
115
117
|
requirements: []
|
116
118
|
rubyforge_project: nori
|
117
|
-
rubygems_version:
|
119
|
+
rubygems_version: 1.8.23
|
118
120
|
signing_key:
|
119
|
-
specification_version:
|
121
|
+
specification_version: 3
|
120
122
|
summary: XML to Hash translator
|
121
123
|
test_files:
|
122
124
|
- spec/nori/api_spec.rb
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: 7a4585ff58e2073a1108c7961be22c7f3caf5c80
|
4
|
-
data.tar.gz: b9ab6223657d1839d7a2e4553b7d5a84452bf4c7
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: 432b9de3992b4d4b16a6bfa2fa2e222dbaf11f478ebac4e1f73f8c565ff8d30952a03ee65d6bdd224fb409c82972340ed25817110aeb6ec396974ff50cb11709
|
7
|
-
data.tar.gz: aae0fa14740a20a9f4e5419261a22ad4733da0a2b841e56dbc080bad205f7bfc98a386bb4cf674d8457e20b6e1b7a6c38af9ee4f76b64fb14cd04d4ee1e6d1a5
|