xmlhasher 0.0.5 → 0.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.
data/README.md CHANGED
@@ -1,16 +1,13 @@
1
1
  # XmlHasher
2
2
 
3
3
  [![Build Status](https://travis-ci.org/cloocher/xmlhasher.png)](https://travis-ci.org/cloocher/xmlhasher)
4
- [![Coverage Status](https://coveralls.io/repos/cloocher/xmlhasher/badge.png?branch=master)](https://coveralls.io/r/cloocher/xmlhasher)
5
4
  [![Gem Version](https://badge.fury.io/rb/xmlhasher.png)](http://badge.fury.io/rb/xmlhasher)
6
5
 
7
6
  Fast XML to Ruby Hash converter
8
7
 
9
8
  ## Installation
10
9
 
11
- ## Installation
12
-
13
- Aggcat is available through [Rubygems](http://rubygems.org/gems/xmlhasher) and can be installed via:
10
+ XmlHasher is available through [Rubygems](http://rubygems.org/gems/xmlhasher) and can be installed via:
14
11
 
15
12
  ```
16
13
  $ gem install xmlhasher
@@ -28,17 +25,27 @@ gem 'xmlhasher'
28
25
  require 'xmlhasher'
29
26
 
30
27
  # XmlHasher global configuration
28
+ #
29
+ # snakecase = true converts all keys to snake case notation
30
+ # ignore_namespaces = true will remove XML namespace attributes
31
+ # string_keys = true will convert all keys to Strings, otherwise they will be Symbols
32
+ #
33
+ # here is default configuration
31
34
  XmlHasher.configure do |config|
32
35
  config.snakecase = true
33
36
  config.ignore_namespaces = true
37
+ config.string_keys = false
34
38
  end
35
39
 
36
40
  # alternatively, specify configuration options when instantiating a Parser
37
41
  parser = XmlHasher::Parser.new(
38
42
  :snakecase => true,
39
43
  :ignore_namespaces => true
44
+ :string_keys => false
40
45
  )
41
46
 
47
+ # by default, XmlHasher will convert all keys to symbols. If you want all keys to be Strings, set :string_keys option to 'true'
48
+
42
49
  # parse XML file
43
50
  XmlHasher.parse(File.new('/path/to/my/file.xml'))
44
51
 
@@ -47,6 +54,33 @@ XmlHasher.parse("<tag1><tag2>content</tag2></tag1>")
47
54
  # => {:tag1=>{:tag2=>"content"}}
48
55
 
49
56
  ```
57
+ ## Benchmarks
58
+
59
+ How fast is it? Try it for yourself - [benchmark.rb](https://github.com/cloocher/xmlhasher/blob/master/benchmark/benchmark.rb)
60
+
61
+ ```
62
+ Converting small xml from text to Hash:
63
+
64
+ user system total real
65
+ activesupport(rexml) 0.380000 0.000000 0.380000 ( 0.385326)
66
+ activesupport(libxml) 0.060000 0.000000 0.060000 ( 0.062008)
67
+ activesupport(nokogiri) 0.090000 0.000000 0.090000 ( 0.089466)
68
+ xmlsimple 0.480000 0.010000 0.490000 ( 0.490938)
69
+ nori 0.120000 0.000000 0.120000 ( 0.123612)
70
+ xmlhasher 0.010000 0.000000 0.010000 ( 0.017366)
71
+
72
+ Converting large xml from file to Hash:
73
+
74
+ user system total real
75
+ activesupport(rexml) 57.230000 0.240000 57.470000 ( 57.460510)
76
+ activesupport(libxml) # Segmentation fault
77
+ activesupport(nokogiri) 12.650000 0.250000 12.900000 ( 12.908073)
78
+ xmlsimple 49.980000 0.160000 50.140000 ( 50.140775)
79
+ nori 15.590000 0.110000 15.700000 ( 15.697411)
80
+ xmlhasher 4.290000 0.030000 4.320000 ( 4.316379)
81
+ ```
82
+ Note: benchmarks were generated on a Macbook Pro using Ruby 1.9.3p392
83
+
50
84
  ## Requirements
51
85
 
52
86
  * Ruby 1.8.7 or higher
@@ -0,0 +1,95 @@
1
+ $:.push File.expand_path('../../lib', __FILE__)
2
+
3
+ require 'benchmark'
4
+ require 'xmlhasher'
5
+ begin
6
+ require 'nori'
7
+ rescue
8
+ puts "nori gem in not installed, run 'gem install nori'"
9
+ end
10
+ begin
11
+ require 'active_support/core_ext/hash/conversions'
12
+ rescue
13
+ puts "active_support gem in not installed, run 'gem install activesupport'"
14
+ end
15
+ begin
16
+ require 'xmlsimple'
17
+ rescue
18
+ puts "xmlsimple gem in not installed, run 'gem install xml-simple'"
19
+ end
20
+ begin
21
+ require 'nokogiri'
22
+ rescue
23
+ puts "nokogiri gem in not installed, run 'gem install nokogiri'"
24
+ end
25
+ begin
26
+ require 'libxml'
27
+ rescue
28
+ puts "libxml gem in not installed, run 'gem install libxml-ruby'"
29
+ end
30
+
31
+
32
+ runs = 100
33
+ xml = File.read(File.expand_path('../../test/fixtures/institution.xml', __FILE__))
34
+ puts 'Converting small xml from text to Hash:'
35
+ Benchmark.bm 10 do |x|
36
+ ActiveSupport::XmlMini.backend = ActiveSupport::XmlMini_REXML
37
+ x.report 'activesupport(rexml) ' do
38
+ runs.times { Hash.from_xml(xml) }
39
+ end
40
+
41
+ ActiveSupport::XmlMini.backend = 'LibXML'
42
+ x.report 'activesupport(libxml) ' do
43
+ runs.times { Hash.from_xml(xml) }
44
+ end
45
+
46
+ ActiveSupport::XmlMini.backend = 'Nokogiri'
47
+ x.report 'activesupport(nokogiri)' do
48
+ runs.times { Hash.from_xml(xml) }
49
+ end
50
+
51
+ x.report 'xmlsimple ' do
52
+ runs.times { XmlSimple.xml_in(xml) }
53
+ end
54
+
55
+ x.report 'nori ' do
56
+ runs.times { Nori.new(:advanced_typecasting => false).parse(xml) }
57
+ end
58
+
59
+ x.report 'xmlhasher ' do
60
+ runs.times { XmlHasher.parse(xml) }
61
+ end
62
+ end
63
+
64
+ puts
65
+ runs = 5
66
+ path = File.expand_path('../../test/fixtures/institutions.xml', __FILE__)
67
+ puts 'Converting large xml from file to Hash:'
68
+ Benchmark.bm 5 do |x|
69
+ ActiveSupport::XmlMini.backend = ActiveSupport::XmlMini_REXML
70
+ x.report 'activesupport(rexml) ' do
71
+ runs.times { Hash.from_xml(File.new(path)) }
72
+ end
73
+
74
+ ActiveSupport::XmlMini.backend = 'LibXML'
75
+ x.report 'activesupport(libxml) ' do
76
+ #runs.times { Hash.from_xml(File.new(path)) } # Segmentation fault
77
+ end
78
+
79
+ ActiveSupport::XmlMini.backend = 'Nokogiri'
80
+ x.report 'activesupport(nokogiri)' do
81
+ runs.times { Hash.from_xml(File.new(path)) }
82
+ end
83
+
84
+ x.report 'xmlsimple ' do
85
+ runs.times { XmlSimple.xml_in(path) }
86
+ end
87
+
88
+ x.report 'nori ' do
89
+ runs.times { Nori.new(:advanced_typecasting => false).parse(File.new(path).read) } # Nori doesn't support reading from a stream, load the file in memory
90
+ end
91
+
92
+ x.report 'xmlhasher ' do
93
+ runs.times { XmlHasher.parse(File.new(path)) }
94
+ end
95
+ end
@@ -1,9 +1,9 @@
1
1
  module XmlHasher
2
2
  module Configurable
3
3
 
4
- attr_writer :snakecase, :ignore_namespaces
4
+ attr_writer :snakecase, :ignore_namespaces, :string_keys
5
5
 
6
- KEYS = [:snakecase, :ignore_namespaces]
6
+ KEYS = [:snakecase, :ignore_namespaces, :string_keys]
7
7
 
8
8
  def configure
9
9
  yield self
@@ -40,6 +40,7 @@ module XmlHasher
40
40
  def transform(name)
41
41
  name = name.to_s.split(':').last if @options[:ignore_namespaces]
42
42
  name = Util.snakecase(name) if @options[:snakecase]
43
+ name = name.to_sym unless @options[:string_keys]
43
44
  name
44
45
  end
45
46
 
@@ -1,7 +1,7 @@
1
1
  module XmlHasher
2
2
  module Util
3
3
  def self.snakecase(str)
4
- str.to_s.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').gsub(/([a-z])([A-Z])/, '\1_\2').downcase.tr('-', '_').to_sym
4
+ str.to_s.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').gsub(/([a-z])([A-Z])/, '\1_\2').downcase.tr('-', '_')
5
5
  end
6
6
  end
7
7
  end
@@ -1,3 +1,3 @@
1
1
  module XmlHasher
2
- VERSION = '0.0.5'
2
+ VERSION = '0.0.6'
3
3
  end
data/test/test_helper.rb CHANGED
@@ -9,7 +9,6 @@ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
9
9
  Coveralls::SimpleCov::Formatter
10
10
  ]
11
11
  SimpleCov.start
12
- Coveralls.wear!
13
12
 
14
13
  require 'test/unit'
15
14
  require 'xmlhasher'
@@ -226,6 +226,16 @@ class XmlhasherTest < Test::Unit::TestCase
226
226
  assert_equal expected, XmlHasher::Parser.new(options).parse(xml)
227
227
  end
228
228
 
229
+ def test_snakecasing_string_elements
230
+ options = {
231
+ :snakecase => true,
232
+ :string_keys => true
233
+ }
234
+ xml = %[<my-tag><MyTag2>content</MyTag2></my-tag>]
235
+ expected = {'my_tag' => {'my_tag2' => 'content'}}
236
+ assert_equal expected, XmlHasher::Parser.new(options).parse(xml)
237
+ end
238
+
229
239
  def test_empty_tag
230
240
  xml = %[<tag></tag>]
231
241
  expected = {:tag => nil}
@@ -6,18 +6,22 @@ class XmlhasherTest < Test::Unit::TestCase
6
6
  configurable = XmlHasher.configure do |config|
7
7
  config.snakecase = true
8
8
  config.ignore_namespaces = true
9
+ config.string_keys = true
9
10
  end
10
11
  assert_equal true, configurable.instance_variable_get(:'@snakecase')
11
12
  assert_equal true, configurable.instance_variable_get(:'@ignore_namespaces')
13
+ assert_equal true, configurable.instance_variable_get(:'@string_keys')
12
14
  end
13
15
 
14
16
  def test_configure_settings_all_off
15
17
  configurable = XmlHasher.configure do |config|
16
18
  config.snakecase = false
17
19
  config.ignore_namespaces = false
20
+ config.string_keys = false
18
21
  end
19
22
  assert_equal false, configurable.instance_variable_get(:'@snakecase')
20
23
  assert_equal false, configurable.instance_variable_get(:'@ignore_namespaces')
24
+ assert_equal false, configurable.instance_variable_get(:'@string_keys')
21
25
  end
22
26
 
23
27
  def test_parser
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xmlhasher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-04-24 00:00:00.000000000 Z
12
+ date: 2013-09-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ox
@@ -88,6 +88,7 @@ files:
88
88
  - LICENSE.txt
89
89
  - README.md
90
90
  - Rakefile
91
+ - benchmark/benchmark.rb
91
92
  - lib/xmlhasher.rb
92
93
  - lib/xmlhasher/configurable.rb
93
94
  - lib/xmlhasher/handler.rb