xmlhasher 1.0.1 → 1.0.6

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.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'ox'
2
4
  require 'escape_utils'
3
5
 
@@ -6,6 +8,9 @@ module XmlHasher
6
8
  def initialize(options = {})
7
9
  @options = options
8
10
  @stack = []
11
+ @transform_cache = {}
12
+
13
+ super()
9
14
  end
10
15
 
11
16
  def to_hash
@@ -17,16 +22,20 @@ module XmlHasher
17
22
  end
18
23
 
19
24
  def attr(name, value)
20
- unless ignore_attribute?(name)
21
- @stack.last.attributes[transform(name)] = escape(value) unless @stack.empty?
22
- end
25
+ return if ignore_attribute?(name) || @stack.empty?
26
+
27
+ @stack.last.attributes[transform(name)] = escape(value)
23
28
  end
24
29
 
25
30
  def text(value)
26
31
  @stack.last.text = escape(value)
27
32
  end
28
33
 
29
- def end_element(name)
34
+ def cdata(str)
35
+ @stack.last.text = escape(str)
36
+ end
37
+
38
+ def end_element(_name)
30
39
  if @stack.size == 1
31
40
  @hash = @stack.pop.to_hash
32
41
  else
@@ -38,9 +47,14 @@ module XmlHasher
38
47
  private
39
48
 
40
49
  def transform(name)
50
+ return @transform_cache[name] if @transform_cache[name]
51
+
52
+ orig_name = name
53
+
41
54
  name = name.to_s.split(':').last if @options[:ignore_namespaces]
42
55
  name = Util.snakecase(name) if @options[:snakecase]
43
- name = name.to_sym unless @options[:string_keys]
56
+ name = @options[:string_keys] ? name.to_s : name.to_sym
57
+ @transform_cache[orig_name] = name
44
58
  name
45
59
  end
46
60
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module XmlHasher
2
4
  class Node
3
5
  attr_accessor :name, :attributes, :children, :text
@@ -9,21 +11,36 @@ module XmlHasher
9
11
  end
10
12
 
11
13
  def to_hash
12
- h = {}
13
- if text && !text.empty?
14
- h[name] = text
15
- else
16
- h[name] = attributes.inject({}) { |r, (key, value)| r[key] = value if !value.nil? && !value.to_s.empty?; r }
17
- if children.size == 1
18
- child = children.first
19
- h[name].merge!(child.to_hash)
20
- else
21
- h[name].merge!(children.group_by { |child| child.name }.inject({}) { |r, (k, v)| v.length == 1 ? r.merge!(v.first.to_hash) : r[k] = v.map { |c| c.to_hash[c.name] }; r })
14
+ node_content = content
15
+ { name => node_content.empty? ? nil : node_content }
16
+ end
17
+
18
+ private
19
+
20
+ def content
21
+ return text if text && !text.empty?
22
+
23
+ attributes_to_hash.merge(children_to_hash)
24
+ end
25
+
26
+ def attributes_to_hash
27
+ attributes.each_with_object({}) do |(key, value), data|
28
+ next if value.nil? || value.to_s.empty?
29
+
30
+ data[key] = value
31
+ end
32
+ end
33
+
34
+ def children_to_hash
35
+ return children.first.to_hash if children.size == 1
36
+
37
+ children.group_by(&:name).each_with_object({}) do |(key, nodes), data|
38
+ next data.merge!(nodes.first.to_hash) if nodes.length == 1
39
+
40
+ data[key] = nodes.map do |node|
41
+ node.to_hash[node.name]
22
42
  end
23
43
  end
24
- h[name] = nil if h[name].empty?
25
- h
26
44
  end
27
45
  end
28
46
  end
29
-
@@ -1,8 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'stringio'
2
4
 
3
5
  module XmlHasher
4
6
  class Parser
5
-
6
7
  def initialize(options = {})
7
8
  @options = options
8
9
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module XmlHasher
2
4
  module Util
3
5
  def self.snakecase(str)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module XmlHasher
2
- VERSION = '1.0.1'
4
+ VERSION = '1.0.6'
3
5
  end
data/scripts/ci ADDED
@@ -0,0 +1,26 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ init_ruby_version() {
6
+ echo "Using $(ruby -v)"
7
+ echo "$(cut -d'@' -f1 <<<"$(rvm current)")" > .ruby-version
8
+ }
9
+
10
+ run_code_quality_checks() {
11
+ if [[ "$(rvm current)" != *"2.0.0"* ]]; then
12
+ bundle exec rubocop .
13
+ fi
14
+ }
15
+
16
+ run_tests() {
17
+ bundle exec rake test
18
+ }
19
+
20
+ main() {
21
+ init_ruby_version &&
22
+ run_code_quality_checks &&
23
+ run_tests
24
+ }
25
+
26
+ main
data/xmlhasher.gemspec CHANGED
@@ -1,5 +1,6 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'xmlhasher/version'
5
6
 
@@ -8,22 +9,26 @@ Gem::Specification.new do |spec|
8
9
  spec.version = XmlHasher::VERSION
9
10
  spec.authors = ['Gene Drabkin']
10
11
  spec.email = ['gene.drabkin@gmail.com']
11
- spec.description = %q{Fast XML to Ruby Hash converter}
12
- spec.summary = %q{XmlHasher converts XML to Ruby Hash}
12
+ spec.description = 'Fast XML to Ruby Hash converter'
13
+ spec.summary = 'XmlHasher converts XML to Ruby Hash'
13
14
  spec.homepage = 'https://github.com/cloocher/xmlhasher'
14
15
  spec.license = 'MIT'
15
16
 
16
- spec.files = `git ls-files`.split($/)
17
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
19
20
  spec.require_paths = ['lib']
20
21
 
21
- spec.required_ruby_version = '>= 1.8.7'
22
+ spec.required_ruby_version = Gem::Requirement.new('>= 1.9.3')
22
23
  spec.required_rubygems_version = '>= 1.3.6'
23
24
 
24
- spec.add_dependency 'ox', '>= 2.2.4'
25
- spec.add_dependency 'escape_utils', '>= 1.2.0'
25
+ spec.add_dependency 'escape_utils', '~> 1.2'
26
+ spec.add_dependency 'ox', '~> 2.11'
26
27
 
27
- spec.add_development_dependency 'rake'
28
- spec.add_development_dependency 'bundler'
28
+ spec.add_development_dependency 'bundler', '>= 1.6', '< 3'
29
+ spec.add_development_dependency 'coveralls', '~> 0.8.21'
30
+ spec.add_development_dependency 'minitest', '~> 5.10'
31
+ spec.add_development_dependency 'rake', '~> 12'
32
+ spec.add_development_dependency 'simplecov', '~> 0.14.1'
33
+ spec.add_development_dependency 'test-unit', '~> 3.2'
29
34
  end
metadata CHANGED
@@ -1,71 +1,133 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xmlhasher
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gene Drabkin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-20 00:00:00.000000000 Z
11
+ date: 2021-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: escape_utils
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.2'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: ox
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
- - - ">="
31
+ - - "~>"
18
32
  - !ruby/object:Gem::Version
19
- version: 2.2.4
33
+ version: '2.11'
20
34
  type: :runtime
21
35
  prerelease: false
22
36
  version_requirements: !ruby/object:Gem::Requirement
23
37
  requirements:
24
- - - ">="
38
+ - - "~>"
25
39
  - !ruby/object:Gem::Version
26
- version: 2.2.4
40
+ version: '2.11'
27
41
  - !ruby/object:Gem::Dependency
28
- name: escape_utils
42
+ name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - ">="
32
46
  - !ruby/object:Gem::Version
33
- version: 1.2.0
34
- type: :runtime
47
+ version: '1.6'
48
+ - - "<"
49
+ - !ruby/object:Gem::Version
50
+ version: '3'
51
+ type: :development
35
52
  prerelease: false
36
53
  version_requirements: !ruby/object:Gem::Requirement
37
54
  requirements:
38
55
  - - ">="
39
56
  - !ruby/object:Gem::Version
40
- version: 1.2.0
57
+ version: '1.6'
58
+ - - "<"
59
+ - !ruby/object:Gem::Version
60
+ version: '3'
61
+ - !ruby/object:Gem::Dependency
62
+ name: coveralls
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: 0.8.21
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: 0.8.21
75
+ - !ruby/object:Gem::Dependency
76
+ name: minitest
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '5.10'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '5.10'
41
89
  - !ruby/object:Gem::Dependency
42
90
  name: rake
43
91
  requirement: !ruby/object:Gem::Requirement
44
92
  requirements:
45
- - - ">="
93
+ - - "~>"
46
94
  - !ruby/object:Gem::Version
47
- version: '0'
95
+ version: '12'
48
96
  type: :development
49
97
  prerelease: false
50
98
  version_requirements: !ruby/object:Gem::Requirement
51
99
  requirements:
52
- - - ">="
100
+ - - "~>"
53
101
  - !ruby/object:Gem::Version
54
- version: '0'
102
+ version: '12'
55
103
  - !ruby/object:Gem::Dependency
56
- name: bundler
104
+ name: simplecov
57
105
  requirement: !ruby/object:Gem::Requirement
58
106
  requirements:
59
- - - ">="
107
+ - - "~>"
60
108
  - !ruby/object:Gem::Version
61
- version: '0'
109
+ version: 0.14.1
62
110
  type: :development
63
111
  prerelease: false
64
112
  version_requirements: !ruby/object:Gem::Requirement
65
113
  requirements:
66
- - - ">="
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: 0.14.1
117
+ - !ruby/object:Gem::Dependency
118
+ name: test-unit
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '3.2'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
67
129
  - !ruby/object:Gem::Version
68
- version: '0'
130
+ version: '3.2'
69
131
  description: Fast XML to Ruby Hash converter
70
132
  email:
71
133
  - gene.drabkin@gmail.com
@@ -74,14 +136,17 @@ extensions: []
74
136
  extra_rdoc_files: []
75
137
  files:
76
138
  - ".gitignore"
139
+ - ".rubocop.yml"
77
140
  - ".ruby-gemset"
78
141
  - ".ruby-version"
79
142
  - ".travis.yml"
143
+ - CHANGELOG.md
80
144
  - Gemfile
81
145
  - LICENSE.txt
82
146
  - README.md
83
147
  - Rakefile
84
148
  - benchmark/benchmark.rb
149
+ - bin/rake
85
150
  - lib/xmlhasher.rb
86
151
  - lib/xmlhasher/configurable.rb
87
152
  - lib/xmlhasher/handler.rb
@@ -89,11 +154,7 @@ files:
89
154
  - lib/xmlhasher/parser.rb
90
155
  - lib/xmlhasher/util.rb
91
156
  - lib/xmlhasher/version.rb
92
- - test/fixtures/institution.xml
93
- - test/fixtures/institutions.xml
94
- - test/test_helper.rb
95
- - test/xmlhasher/parser_test.rb
96
- - test/xmlhasher/xmlhasher_test.rb
157
+ - scripts/ci
97
158
  - xmlhasher.gemspec
98
159
  homepage: https://github.com/cloocher/xmlhasher
99
160
  licenses:
@@ -107,21 +168,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
107
168
  requirements:
108
169
  - - ">="
109
170
  - !ruby/object:Gem::Version
110
- version: 1.8.7
171
+ version: 1.9.3
111
172
  required_rubygems_version: !ruby/object:Gem::Requirement
112
173
  requirements:
113
174
  - - ">="
114
175
  - !ruby/object:Gem::Version
115
176
  version: 1.3.6
116
177
  requirements: []
117
- rubyforge_project:
118
- rubygems_version: 2.5.1
178
+ rubygems_version: 3.1.2
119
179
  signing_key:
120
180
  specification_version: 4
121
181
  summary: XmlHasher converts XML to Ruby Hash
122
- test_files:
123
- - test/fixtures/institution.xml
124
- - test/fixtures/institutions.xml
125
- - test/test_helper.rb
126
- - test/xmlhasher/parser_test.rb
127
- - test/xmlhasher/xmlhasher_test.rb
182
+ test_files: []
@@ -1,43 +0,0 @@
1
- <InstitutionDetail xmlns="http://schema.intuit.com/platform/fdatafeed/account/v1"
2
- xmlns:ns2="http://schema.intuit.com/platform/fdatafeed/common/v1">
3
- <institutionId>100000</institutionId>
4
- <institutionName>CCBank</institutionName>
5
- <homeUrl>http://www.example.com</homeUrl>
6
- <phoneNumber>123-456-7890</phoneNumber>
7
- <address>
8
- <ns2:address1>100 Main Street</ns2:address1>
9
- <ns2:city>Anytown</ns2:city>
10
- <ns2:state>CA</ns2:state>
11
- <ns2:postalCode>94043</ns2:postalCode>
12
- <ns2:country>USA</ns2:country>
13
- </address>
14
- <emailAddress>CustomerCentralBank@intuit.com</emailAddress>
15
- <currencyCode>ANG</currencyCode>
16
- <locale>
17
- <language>en</language>
18
- </locale>
19
- <keys>
20
- <key>
21
- <name>Banking Userid</name>
22
- <status>Active</status>
23
- <valueLengthMin>1</valueLengthMin>
24
- <valueLengthMax>100</valueLengthMax>
25
- <displayFlag>true</displayFlag>
26
- <displayOrder>1</displayOrder>
27
- <mask>false</mask>
28
- <instructions>2</instructions>
29
- <description>2</description>
30
- </key>
31
- <key>
32
- <name>Banking Password</name>
33
- <status>Active</status>
34
- <valueLengthMin>1</valueLengthMin>
35
- <valueLengthMax>100</valueLengthMax>
36
- <displayFlag>false</displayFlag>
37
- <displayOrder>2</displayOrder>
38
- <mask>true</mask>
39
- <instructions>2</instructions>
40
- <description>2</description>
41
- </key>
42
- </keys>
43
- </InstitutionDetail>