xmlhasher 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
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