oxml 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ef18bf4918b7cecec5e065a1438d1ae31189db1cb4ff1926a1dcaad578bf513c
4
+ data.tar.gz: 02b8fc7882d4bc244a2dd0c126fa1e37671e9036e6617326f158036157e1f935
5
+ SHA512:
6
+ metadata.gz: 12dbb1470019dcf00b6cdb1b90a4e0507daf7c20b07e11b42d21ade3d69aac454917e4eef08e9a40f7771acb1cca72019f93f2e80344088c515461bb65feb237
7
+ data.tar.gz: 8ea918b36f0c1bd55d940740710812f1a458e614f9fdc1ed860ac96885a5ae1bf893a705563cc8024f94a562bf860ea4c9e6a6d6aa46f2947b46f68944989f65
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OXML
4
+ class Parser
5
+ EMPTY_STR = ''
6
+ TRUE_STR = 'true'
7
+ FALSE_STR = 'false'
8
+ DATE_TIME = /^-?\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?$/.freeze
9
+ DATE = /^-?\d{4}-\d{2}-\d{2}(?:Z|[+-]\d{2}:?\d{2})?$/.freeze
10
+ TIME = /^\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?$/.freeze
11
+
12
+ def initialize(options = {})
13
+ @memo = {}
14
+ @arr = []
15
+ @map = {}
16
+ @name = nil
17
+ @strip_namespaces = options.fetch(:strip_namespaces, false)
18
+ @delete_namespace_attributes = options.fetch(:delete_namespace_attributes, false)
19
+ @advanced_typecasting = options.fetch(:advanced_typecasting, false)
20
+ end
21
+
22
+ def to_h
23
+ @memo.to_h
24
+ end
25
+
26
+ def attr(name, str)
27
+ return if @delete_namespace_attributes
28
+
29
+ return if name == :version
30
+ return if name == :encoding
31
+
32
+ start_element("@#{name}")
33
+ text(str)
34
+ end_element(name)
35
+ end
36
+
37
+ def start_element(name)
38
+ @arr.push(@memo)
39
+
40
+ if @strip_namespaces && name.start_with?('@')
41
+ @name = name.to_sym
42
+ elsif @strip_namespaces
43
+ @name = @map[name] ||= Utils.snakecase(name).split(':').last.to_sym
44
+ else
45
+ @name = @map[name] ||= Utils.snakecase(name).to_sym
46
+ end
47
+
48
+ @memo = {}
49
+ text(@memo)
50
+ end
51
+
52
+ def end_element(_name)
53
+ @memo = @arr.pop
54
+ end
55
+
56
+ def text(value)
57
+ if @arr.last[@name].is_a?(Array)
58
+ @arr.last[@name].pop unless value == @memo
59
+ @arr.last[@name] << cast(value)
60
+ elsif @arr.last[@name] && value == @memo
61
+ @arr.last[@name] = [@arr.last[@name], value]
62
+ else
63
+ @arr.last[@name] = cast(value)
64
+ end
65
+ end
66
+
67
+ private
68
+
69
+ def cast(value)
70
+ return value unless @advanced_typecasting
71
+
72
+ case value
73
+ when EMPTY_STR then nil
74
+ when TRUE_STR then true
75
+ when FALSE_STR then false
76
+ when DATE_TIME then DateTime.parse(value)
77
+ when DATE then Date.parse(value)
78
+ when TIME then Time.parse(value)
79
+ else value
80
+ end
81
+ end
82
+ end
83
+ end
data/lib/oxml/utils.rb ADDED
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OXML
4
+ module Utils
5
+ module_function
6
+
7
+ def snakecase(input)
8
+ input
9
+ .to_s
10
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
11
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
12
+ .downcase
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OXML
4
+ VERSION = '0.1.0'
5
+ end
data/lib/oxml.rb ADDED
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ox'
4
+
5
+ require_relative 'oxml/version'
6
+ require_relative 'oxml/utils'
7
+ require_relative 'oxml/parser'
8
+
9
+ module OXML
10
+ module_function
11
+
12
+ def parse(xml, options = {})
13
+ handler = Parser.new(options)
14
+ Ox.sax_parse(handler, xml)
15
+ handler.to_h
16
+ end
17
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: oxml
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - xkwd
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-11-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ox
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.14'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.14'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.0'
41
+ description: Fast XML to Hash parser built on top of the Ox gem (a native C extension)
42
+ email:
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - lib/oxml.rb
48
+ - lib/oxml/parser.rb
49
+ - lib/oxml/utils.rb
50
+ - lib/oxml/version.rb
51
+ homepage: https://github.com/xkwd/oxml
52
+ licenses:
53
+ - MIT
54
+ metadata: {}
55
+ post_install_message:
56
+ rdoc_options: []
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '2.7'
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ requirements: []
70
+ rubygems_version: 3.4.21
71
+ signing_key:
72
+ specification_version: 4
73
+ summary: Fast XML to Hash parser
74
+ test_files: []