oxml 0.1.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.
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: []