multi_xml 0.6.0 → 0.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: add5ff8df4d736d143b1d83c38c5f1b8b35d21cd
4
- data.tar.gz: ec8e8a3657ff340a9a4abefa2561e44dfee8371d
2
+ SHA256:
3
+ metadata.gz: 7bebe7a08139024835279d7ffc78a7d86d0cb9a5ff59787068e044f7c75dc6f9
4
+ data.tar.gz: a2f579d2e18a266fe9573174de87ac960fcf867081705a2a6feb458bfa573225
5
5
  SHA512:
6
- metadata.gz: 1cb437e88276aa09e33c5b10a1e32bbf181ecae9543976ab13acc4ca458b00b1315a59f1e3e1cd95fd24e47559a85058585578ba16441ac83c98ffa81c5ee902
7
- data.tar.gz: 1931768faabe059174c01e24d12f9b1c8bcc0c9717891ec9ba9098f55c98535ad2a0efab7dcc4bfd756a569f137bf86e4b45b652a182652e6a468393103de9f5
6
+ metadata.gz: be4ffea0dd836f1d1d1baf73ffded7de5a79fdc53a5b039b5e7fd0a615a786ca08dc0a7bbf5561266cdade44a9cb3c2382fe6e35a54599876f77ec74ec937d42
7
+ data.tar.gz: d579ab46f0122a1011704e397062b5d9e648eeaae85a8baa30ac8eda7f3d1cdaa9e57fe1922e6e3e7ac608ef9607033c1547773dbb2eb1fe6785176a3471764d
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --order random
data/.rubocop.yml ADDED
@@ -0,0 +1,54 @@
1
+ require:
2
+ - rubocop-performance
3
+ - rubocop-rake
4
+ - rubocop-rspec
5
+ - standard
6
+ - standard-performance
7
+
8
+ AllCops:
9
+ NewCops: enable
10
+ TargetRubyVersion: 3.1
11
+
12
+ Layout/ArgumentAlignment:
13
+ EnforcedStyle: with_fixed_indentation
14
+ IndentationWidth: 2
15
+
16
+ Layout/CaseIndentation:
17
+ EnforcedStyle: end
18
+
19
+ Layout/EndAlignment:
20
+ EnforcedStyleAlignWith: start_of_line
21
+
22
+ Layout/LineLength:
23
+ Max: 140
24
+
25
+ Layout/ParameterAlignment:
26
+ EnforcedStyle: with_fixed_indentation
27
+ IndentationWidth: 2
28
+
29
+ Layout/SpaceInsideHashLiteralBraces:
30
+ EnforcedStyle: no_space
31
+
32
+ Metrics/ParameterLists:
33
+ CountKeywordArgs: false
34
+
35
+ Style/Alias:
36
+ EnforcedStyle: prefer_alias_method
37
+
38
+ Style/Documentation:
39
+ Enabled: false
40
+
41
+ Style/FrozenStringLiteralComment:
42
+ EnforcedStyle: never
43
+
44
+ Style/OpenStructUse:
45
+ Enabled: false
46
+
47
+ Style/StringLiterals:
48
+ EnforcedStyle: double_quotes
49
+
50
+ Style/StringLiteralsInInterpolation:
51
+ EnforcedStyle: double_quotes
52
+
53
+ Style/TernaryParentheses:
54
+ EnforcedStyle: require_parentheses
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ 0.7.0
2
+ -----
3
+ * [Add support for Ruby 3.3](https://github.com/sferik/multi_xml/pull/67)
4
+ * [Drop support for Ruby 3.0](https://github.com/sferik/multi_xml/commit/eec72c56307fede3a93f1a61553587cb278b0c8a) [and](https://github.com/sferik/multi_xml/commit/6a6dec80a36c30774a5525b45f71d346fb561e69) [earlier](https://github.com/sferik/multi_xml/commit/e7dad37a0a0be8383a26ffe515c575b5b4d04588)
5
+ * [Don't mutate strings](https://github.com/sferik/multi_xml/commit/71be3fff4afb0277a7e1c47c5f1f4b6106a8eb45)
6
+
7
+ 0.6.0
8
+ -----
9
+ * [Duplexed Streams](https://github.com/sferik/multi_xml/pull/45)
10
+ * [Support for Oga](https://github.com/sferik/multi_xml/pull/47)
11
+ * [Integer unification for Ruby 2.4](https://github.com/sferik/multi_xml/pull/54)
12
+
1
13
  0.5.5
2
14
  -----
3
15
  * [Fix symbolize_keys function](https://github.com/sferik/multi_xml/commit/a4cae3aeb690999287cd30206399abaa5ce1ae81)
data/Gemfile ADDED
@@ -0,0 +1,21 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "libxml-ruby", require: nil, platforms: :ruby
4
+ gem "nokogiri", require: nil
5
+ gem "oga", ">= 2.3", require: nil
6
+ gem "ox", require: nil, platforms: :ruby
7
+ gem "rexml", require: nil
8
+
9
+ gem "rake", ">= 13.2.1"
10
+ gem "rspec", ">= 3.12"
11
+ gem "rubocop", ">= 1.62.1"
12
+ gem "rubocop-performance", ">= 1.20.2"
13
+ gem "rubocop-rake", ">= 0.6"
14
+ gem "rubocop-rspec", ">= 2.24"
15
+ gem "simplecov", ">= 0.22"
16
+ gem "standard", ">= 1.35.1"
17
+ gem "standard-performance", ">= 1.3.1"
18
+ gem "yard", ">= 0.9.36"
19
+ gem "yardstick", ">= 0.9.9"
20
+
21
+ gemspec
data/LICENSE.md CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010-2013 Erik Michaels-Ober
1
+ Copyright (c) 2010-2024 Erik Berlin
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,17 +1,5 @@
1
1
  # MultiXML
2
2
 
3
- [![Gem Version](http://img.shields.io/gem/v/multi_xml.svg)][gem]
4
- [![Build Status](http://img.shields.io/travis/sferik/multi_xml.svg)][travis]
5
- [![Dependency Status](http://img.shields.io/gemnasium/sferik/multi_xml.svg)][gemnasium]
6
- [![Code Climate](http://img.shields.io/codeclimate/github/sferik/multi_xml.svg)][codeclimate]
7
- [![Coverage Status](http://img.shields.io/coveralls/sferik/multi_xml.svg)][coveralls]
8
-
9
- [gem]: https://rubygems.org/gems/multi_xml
10
- [travis]: http://travis-ci.org/sferik/multi_xml
11
- [gemnasium]: https://gemnasium.com/sferik/multi_xml
12
- [codeclimate]: https://codeclimate.com/github/sferik/multi_xml
13
- [coveralls]: https://coveralls.io/r/sferik/multi_xml
14
-
15
3
  A generic swappable back-end for XML parsing
16
4
 
17
5
  ## Installation
@@ -23,10 +11,6 @@ A generic swappable back-end for XML parsing
23
11
  [documentation]: http://rdoc.info/gems/multi_xml
24
12
 
25
13
  ## Usage Examples
26
- Lots of Ruby libraries utilize XML parsing in some form, and everyone has their
27
- favorite XML library. In order to best support multiple XML parsers and
28
- libraries, `multi_xml` is a general-purpose swappable XML backend library. You
29
- use it like so:
30
14
  ```ruby
31
15
  require 'multi_xml'
32
16
 
@@ -54,24 +38,19 @@ The `parser` setter takes either a symbol or a class (to allow for custom XML
54
38
  parsers) that responds to `.parse` at the class level.
55
39
 
56
40
  MultiXML tries to have intelligent defaulting. That is, if you have any of the
57
- supported parsers already loaded, it will utilize them before attempting to
58
- load any. When loading, libraries are ordered by speed: first Ox, then LibXML,
41
+ supported parsers already loaded, it will use them before attempting to load
42
+ a new one. When loading, libraries are ordered by speed: first Ox, then LibXML,
59
43
  then Nokogiri, and finally REXML.
60
44
 
61
45
  ## Supported Ruby Versions
62
- This library aims to support and is [tested against][travis] the following Ruby
46
+ This library aims to support and is tested against the following Ruby
63
47
  implementations:
64
48
 
65
- * Ruby 1.9.3
66
- * Ruby 2.0.0
67
- * Ruby 2.1
68
- * Ruby 2.2
69
- * Ruby 2.3
70
- * [JRuby 9000][jruby]
71
-
72
- [jruby]: http://jruby.org/
49
+ * 3.1
50
+ * 3.2
51
+ * 3.3
73
52
 
74
- If something doesn't work on one of these interpreters, it's a bug.
53
+ If something doesn't work on one of these versions, it's a bug.
75
54
 
76
55
  This library may inadvertently work (or seem to work) on other Ruby
77
56
  implementations, however support will only be provided for the versions listed
@@ -90,6 +69,6 @@ MultiXML was inspired by [MultiJSON][].
90
69
  [multijson]: https://github.com/intridea/multi_json/
91
70
 
92
71
  ## Copyright
93
- Copyright (c) 2010-2013 Erik Michaels-Ober. See [LICENSE][] for details.
72
+ Copyright (c) 2010-2024 Erik Berlin. See [LICENSE][] for details.
94
73
 
95
74
  [license]: LICENSE.md
data/Rakefile ADDED
@@ -0,0 +1,33 @@
1
+ require "bundler"
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require "rspec/core/rake_task"
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task test: :spec
8
+
9
+ require "rubocop/rake_task"
10
+ RuboCop::RakeTask.new
11
+
12
+ require "yard"
13
+ YARD::Rake::YardocTask.new do |task|
14
+ task.files = ["lib/**/*.rb", "-", "LICENSE.md"]
15
+ task.options = [
16
+ "--no-private",
17
+ "--protected",
18
+ "--output-dir", "doc/yard",
19
+ "--markup", "markdown"
20
+ ]
21
+ end
22
+
23
+ require "yardstick/rake/measurement"
24
+ Yardstick::Rake::Measurement.new do |measurement|
25
+ measurement.output = "measurement/report.txt"
26
+ end
27
+
28
+ require "yardstick/rake/verify"
29
+ Yardstick::Rake::Verify.new do |verify|
30
+ verify.threshold = 48.8
31
+ end
32
+
33
+ task default: %i[spec rubocop verify_measurements]
@@ -1,9 +1,9 @@
1
- require 'libxml' unless defined?(LibXML)
2
- require 'multi_xml/parsers/libxml2_parser'
1
+ require "libxml" unless defined?(LibXML)
2
+ require "multi_xml/parsers/libxml2_parser"
3
3
 
4
4
  module MultiXml
5
5
  module Parsers
6
- module Libxml #:nodoc:
6
+ module Libxml # :nodoc:
7
7
  include Libxml2Parser
8
8
  extend self
9
9
 
@@ -15,14 +15,14 @@ module MultiXml
15
15
  node_to_hash(LibXML::XML::Parser.io(xml).parse.root)
16
16
  end
17
17
 
18
- private
18
+ private
19
19
 
20
- def each_child(node, &block)
21
- node.each_child(&block)
20
+ def each_child(node, &)
21
+ node.each_child(&)
22
22
  end
23
23
 
24
- def each_attr(node, &block)
25
- node.each_attr(&block)
24
+ def each_attr(node, &)
25
+ node.each_attr(&)
26
26
  end
27
27
 
28
28
  def node_name(node)
@@ -1,6 +1,6 @@
1
1
  module MultiXml
2
2
  module Parsers
3
- module Libxml2Parser #:nodoc:
3
+ module Libxml2Parser # :nodoc:
4
4
  # Convert XML document to hash
5
5
  #
6
6
  # node::
@@ -8,8 +8,8 @@ module MultiXml
8
8
  #
9
9
  # hash::
10
10
  # Hash to merge the converted element into.
11
- def node_to_hash(node, hash = {}) # rubocop:disable AbcSize, CyclomaticComplexity, MethodLength, PerceivedComplexity
12
- node_hash = {MultiXml::CONTENT_ROOT => ''}
11
+ def node_to_hash(node, hash = {}) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
12
+ node_hash = {MultiXml::CONTENT_ROOT => ""}
13
13
 
14
14
  name = node_name(node)
15
15
 
@@ -28,20 +28,18 @@ module MultiXml
28
28
  if c.element?
29
29
  node_to_hash(c, node_hash)
30
30
  elsif c.text? || c.cdata?
31
- node_hash[MultiXml::CONTENT_ROOT] << c.content
31
+ node_hash[MultiXml::CONTENT_ROOT] += c.content
32
32
  end
33
33
  end
34
34
 
35
35
  # Remove content node if it is empty
36
- if node_hash[MultiXml::CONTENT_ROOT].strip.empty?
37
- node_hash.delete(MultiXml::CONTENT_ROOT)
38
- end
36
+ node_hash.delete(MultiXml::CONTENT_ROOT) if node_hash[MultiXml::CONTENT_ROOT].strip.empty?
39
37
 
40
38
  # Handle attributes
41
39
  each_attr(node) do |a|
42
40
  key = node_name(a)
43
41
  v = node_hash[key]
44
- node_hash[key] = (v ? [a.value, v] : a.value)
42
+ node_hash[key] = ((v) ? [a.value, v] : a.value)
45
43
  end
46
44
 
47
45
  hash
@@ -51,21 +49,21 @@ module MultiXml
51
49
  # xml::
52
50
  # XML Document IO to parse
53
51
  def parse(_)
54
- raise(NotImplementedError.new("inheritor should define #{__method__}"))
52
+ raise(NotImplementedError, "inheritor should define #{__method__}")
55
53
  end
56
54
 
57
- private
55
+ private
58
56
 
59
57
  def each_child(*)
60
- raise(NotImplementedError.new("inheritor should define #{__method__}"))
58
+ raise(NotImplementedError, "inheritor should define #{__method__}")
61
59
  end
62
60
 
63
61
  def each_attr(*)
64
- raise(NotImplementedError.new("inheritor should define #{__method__}"))
62
+ raise(NotImplementedError, "inheritor should define #{__method__}")
65
63
  end
66
64
 
67
65
  def node_name(*)
68
- raise(NotImplementedError.new("inheritor should define #{__method__}"))
66
+ raise(NotImplementedError, "inheritor should define #{__method__}")
69
67
  end
70
68
  end
71
69
  end
@@ -1,9 +1,9 @@
1
- require 'nokogiri' unless defined?(Nokogiri)
2
- require 'multi_xml/parsers/libxml2_parser'
1
+ require "nokogiri" unless defined?(Nokogiri)
2
+ require "multi_xml/parsers/libxml2_parser"
3
3
 
4
4
  module MultiXml
5
5
  module Parsers
6
- module Nokogiri #:nodoc:
6
+ module Nokogiri # :nodoc:
7
7
  include Libxml2Parser
8
8
  extend self
9
9
 
@@ -14,17 +14,18 @@ module MultiXml
14
14
  def parse(xml)
15
15
  doc = ::Nokogiri::XML(xml)
16
16
  raise(doc.errors.first) unless doc.errors.empty?
17
+
17
18
  node_to_hash(doc.root)
18
19
  end
19
20
 
20
- private
21
+ private
21
22
 
22
- def each_child(node, &block)
23
- node.children.each(&block)
23
+ def each_child(node, &)
24
+ node.children.each(&)
24
25
  end
25
26
 
26
- def each_attr(node, &block)
27
- node.attribute_nodes.each(&block)
27
+ def each_attr(node, &)
28
+ node.attribute_nodes.each(&)
28
29
  end
29
30
 
30
31
  def node_name(node)
@@ -1,9 +1,9 @@
1
- require 'oga' unless defined?(Oga)
2
- require 'multi_xml/parsers/libxml2_parser'
1
+ require "oga" unless defined?(Oga)
2
+ require "multi_xml/parsers/libxml2_parser"
3
3
 
4
4
  module MultiXml
5
5
  module Parsers
6
- module Oga #:nodoc:
6
+ module Oga # :nodoc:
7
7
  include Libxml2Parser
8
8
  extend self
9
9
 
@@ -16,8 +16,8 @@ module MultiXml
16
16
  node_to_hash(document.children[0])
17
17
  end
18
18
 
19
- def node_to_hash(node, hash = {}) # rubocop:disable AbcSize, CyclomaticComplexity, MethodLength, PerceivedComplexity
20
- node_hash = {MultiXml::CONTENT_ROOT => ''}
19
+ def node_to_hash(node, hash = {}) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
20
+ node_hash = {MultiXml::CONTENT_ROOT => ""}
21
21
 
22
22
  name = node_name(node)
23
23
 
@@ -36,38 +36,36 @@ module MultiXml
36
36
  if c.is_a?(::Oga::XML::Element)
37
37
  node_to_hash(c, node_hash)
38
38
  elsif c.is_a?(::Oga::XML::Text) || c.is_a?(::Oga::XML::Cdata)
39
- node_hash[MultiXml::CONTENT_ROOT] << c.text
39
+ node_hash[MultiXml::CONTENT_ROOT] += c.text
40
40
  end
41
41
  end
42
42
 
43
43
  # Remove content node if it is empty
44
- if node_hash[MultiXml::CONTENT_ROOT].strip.empty?
45
- node_hash.delete(MultiXml::CONTENT_ROOT)
46
- end
44
+ node_hash.delete(MultiXml::CONTENT_ROOT) if node_hash[MultiXml::CONTENT_ROOT].strip.empty?
47
45
 
48
46
  # Handle attributes
49
47
  each_attr(node) do |a|
50
48
  key = node_name(a)
51
49
  v = node_hash[key]
52
- node_hash[key] = (v ? [a.value, v] : a.value)
50
+ node_hash[key] = ((v) ? [a.value, v] : a.value)
53
51
  end
54
52
 
55
53
  hash
56
54
  end
57
55
 
58
- private
56
+ private
59
57
 
60
- def each_child(node, &block)
61
- node.children.each(&block)
58
+ def each_child(node, &)
59
+ node.children.each(&)
62
60
  end
63
61
 
64
- def each_attr(node, &block)
65
- node.attributes.each(&block)
62
+ def each_attr(node, &)
63
+ node.attributes.each(&)
66
64
  end
67
65
 
68
66
  def node_name(node)
69
67
  node.name
70
68
  end
71
- end # Oga
72
- end # Parsers
73
- end # MultiXml
69
+ end
70
+ end
71
+ end
@@ -1,4 +1,4 @@
1
- require 'ox' unless defined?(Ox)
1
+ require "ox" unless defined?(Ox)
2
2
 
3
3
  # Each MultiXml parser is expected to parse an XML document into a Hash. The
4
4
  # conversion rules are:
@@ -20,8 +20,8 @@ require 'ox' unless defined?(Ox)
20
20
 
21
21
  module MultiXml
22
22
  module Parsers
23
- module Ox #:nodoc:
24
- extend self
23
+ module Ox # :nodoc:
24
+ module_function
25
25
 
26
26
  def parse_error
27
27
  Exception
@@ -29,7 +29,7 @@ module MultiXml
29
29
 
30
30
  def parse(io)
31
31
  handler = Handler.new
32
- ::Ox.sax_parse(handler, io, :convert_special => true)
32
+ ::Ox.sax_parse(handler, io, convert_special: true, skip: :skip_return)
33
33
  handler.doc
34
34
  end
35
35
 
@@ -68,7 +68,7 @@ module MultiXml
68
68
  end
69
69
 
70
70
  def error(message, line, column)
71
- raise(Exception.new("#{message} at #{line}:#{column}"))
71
+ raise(StandardError, "#{message} at #{line}:#{column}")
72
72
  end
73
73
 
74
74
  def append(key, value)
@@ -85,7 +85,7 @@ module MultiXml
85
85
  h[key] = value
86
86
  end
87
87
  end
88
- end # Handler
89
- end # Ox
90
- end # Parsers
91
- end # MultiXml
88
+ end
89
+ end
90
+ end
91
+ end
@@ -1,8 +1,8 @@
1
- require 'rexml/document' unless defined?(REXML::Document)
1
+ require "rexml/document" unless defined?(REXML::Document)
2
2
 
3
3
  module MultiXml
4
4
  module Parsers
5
- module Rexml #:nodoc:
5
+ module Rexml # :nodoc:
6
6
  extend self
7
7
 
8
8
  def parse_error
@@ -15,11 +15,12 @@ module MultiXml
15
15
  # XML Document IO to parse
16
16
  def parse(xml)
17
17
  doc = REXML::Document.new(xml)
18
- raise(REXML::ParseException.new("The document #{doc.to_s.inspect} does not have a valid root")) unless doc.root
18
+ raise(REXML::ParseException, "The document #{doc.to_s.inspect} does not have a valid root") unless doc.root
19
+
19
20
  merge_element!({}, doc.root)
20
21
  end
21
22
 
22
- private
23
+ private
23
24
 
24
25
  # Convert an XML element and merge into the hash
25
26
  #
@@ -56,8 +57,7 @@ module MultiXml
56
57
  def merge_texts!(hash, element)
57
58
  if element.has_text?
58
59
  # must use value to prevent double-escaping
59
- texts = ''
60
- element.texts.each { |t| texts << t.value }
60
+ texts = element.texts.map(&:value).join
61
61
  merge!(hash, MultiXml::CONTENT_ROOT, texts)
62
62
  else
63
63
  hash
@@ -1,45 +1,3 @@
1
1
  module MultiXml
2
- module Version
3
- module_function
4
-
5
- # @return [Integer]
6
- def major
7
- 0
8
- end
9
-
10
- # @return [Integer]
11
- def minor
12
- 6
13
- end
14
-
15
- # @return [Integer]
16
- def patch
17
- 0
18
- end
19
-
20
- # @return [Integer, NilClass]
21
- def pre
22
- nil
23
- end
24
-
25
- # @return [Hash]
26
- def to_h
27
- {
28
- :major => major,
29
- :minor => minor,
30
- :patch => patch,
31
- :pre => pre,
32
- }
33
- end
34
-
35
- # @return [Array]
36
- def to_a
37
- [major, minor, patch, pre].compact
38
- end
39
-
40
- # @return [String]
41
- def to_s
42
- to_a.join('.')
43
- end
44
- end
2
+ VERSION = Gem::Version.create("0.7.0")
45
3
  end
data/lib/multi_xml.rb CHANGED
@@ -1,81 +1,83 @@
1
- require 'base64'
2
- require 'bigdecimal'
3
- require 'date'
4
- require 'stringio'
5
- require 'time'
6
- require 'yaml'
7
-
8
- module MultiXml # rubocop:disable ModuleLength
1
+ require "bigdecimal"
2
+ require "date"
3
+ require "stringio"
4
+ require "time"
5
+ require "yaml"
6
+
7
+ module MultiXml # rubocop:disable Metrics/ModuleLength
9
8
  class ParseError < StandardError; end
9
+
10
10
  class NoParserError < StandardError; end
11
+
11
12
  class DisallowedTypeError < StandardError
12
13
  def initialize(type)
13
- super "Disallowed type attribute: #{type.inspect}"
14
+ super("Disallowed type attribute: #{type.inspect}")
14
15
  end
15
16
  end
16
17
 
17
18
  unless defined?(REQUIREMENT_MAP)
18
19
  REQUIREMENT_MAP = [
19
- ['ox', :ox],
20
- ['libxml', :libxml],
21
- ['nokogiri', :nokogiri],
22
- ['rexml/document', :rexml],
23
- ['oga', :oga],
20
+ ["ox", :ox],
21
+ ["libxml", :libxml],
22
+ ["nokogiri", :nokogiri],
23
+ ["rexml/document", :rexml],
24
+ ["oga", :oga]
24
25
  ].freeze
25
26
  end
26
27
 
27
- CONTENT_ROOT = '__content__'.freeze unless defined?(CONTENT_ROOT)
28
+ CONTENT_ROOT = "__content__".freeze unless defined?(CONTENT_ROOT)
28
29
 
29
30
  unless defined?(PARSING)
30
31
  float_proc = proc { |float| float.to_f }
31
- datetime_proc = proc { |time| Time.parse(time).utc rescue DateTime.parse(time).utc } # rubocop:disable RescueModifier
32
+ datetime_proc = proc { |time| Time.parse(time).utc rescue DateTime.parse(time).utc } # rubocop:disable Style/RescueModifier
32
33
 
33
34
  PARSING = {
34
- 'symbol' => proc { |symbol| symbol.to_sym },
35
- 'date' => proc { |date| Date.parse(date) },
36
- 'datetime' => datetime_proc,
37
- 'dateTime' => datetime_proc,
38
- 'integer' => proc { |integer| integer.to_i },
39
- 'float' => float_proc,
40
- 'double' => float_proc,
41
- 'decimal' => proc { |number| BigDecimal(number) },
42
- 'boolean' => proc { |boolean| !%w(0 false).include?(boolean.strip) },
43
- 'string' => proc { |string| string.to_s },
44
- 'yaml' => proc { |yaml| YAML.load(yaml) rescue yaml }, # rubocop:disable RescueModifier
45
- 'base64Binary' => proc { |binary| ::Base64.decode64(binary) },
46
- 'binary' => proc { |binary, entity| parse_binary(binary, entity) },
47
- 'file' => proc { |file, entity| parse_file(file, entity) },
35
+ "symbol" => proc { |symbol| symbol.to_sym },
36
+ "date" => proc { |date| Date.parse(date) },
37
+ "datetime" => datetime_proc,
38
+ "dateTime" => datetime_proc,
39
+ "integer" => proc { |integer| integer.to_i },
40
+ "float" => float_proc,
41
+ "double" => float_proc,
42
+ "decimal" => proc { |number| BigDecimal(number) },
43
+ "boolean" => proc { |boolean| !%w[0 false].include?(boolean.strip) },
44
+ "string" => proc { |string| string.to_s },
45
+ "yaml" => proc { |yaml| YAML.load(yaml) rescue yaml }, # rubocop:disable Style/RescueModifier
46
+ "base64Binary" => proc { |binary| base64_decode(binary) },
47
+ "binary" => proc { |binary, entity| parse_binary(binary, entity) },
48
+ "file" => proc { |file, entity| parse_file(file, entity) }
48
49
  }.freeze
49
50
  end
50
51
 
51
52
  unless defined?(TYPE_NAMES)
52
53
  TYPE_NAMES = {
53
- 'Symbol' => 'symbol',
54
- 'Integer' => 'integer',
55
- 'BigDecimal' => 'decimal',
56
- 'Float' => 'float',
57
- 'TrueClass' => 'boolean',
58
- 'FalseClass' => 'boolean',
59
- 'Date' => 'date',
60
- 'DateTime' => 'datetime',
61
- 'Time' => 'datetime',
62
- 'Array' => 'array',
63
- 'Hash' => 'hash',
54
+ "Symbol" => "symbol",
55
+ "Integer" => "integer",
56
+ "BigDecimal" => "decimal",
57
+ "Float" => "float",
58
+ "TrueClass" => "boolean",
59
+ "FalseClass" => "boolean",
60
+ "Date" => "date",
61
+ "DateTime" => "datetime",
62
+ "Time" => "datetime",
63
+ "Array" => "array",
64
+ "Hash" => "hash"
64
65
  }.freeze
65
66
  end
66
67
 
67
- DISALLOWED_XML_TYPES = %w(symbol yaml).freeze
68
+ DISALLOWED_XML_TYPES = %w[symbol yaml].freeze
68
69
 
69
70
  DEFAULT_OPTIONS = {
70
- :typecast_xml_value => true,
71
- :disallowed_types => DISALLOWED_XML_TYPES,
72
- :symbolize_keys => false,
71
+ typecast_xml_value: true,
72
+ disallowed_types: DISALLOWED_XML_TYPES,
73
+ symbolize_keys: false
73
74
  }.freeze
74
75
 
75
76
  class << self
76
77
  # Get the current parser class.
77
78
  def parser
78
79
  return @parser if defined?(@parser)
80
+
79
81
  self.parser = default_parser
80
82
  @parser
81
83
  end
@@ -91,14 +93,13 @@ module MultiXml # rubocop:disable ModuleLength
91
93
  return :oga if defined?(::Oga)
92
94
 
93
95
  REQUIREMENT_MAP.each do |library, parser|
94
- begin
95
- require library
96
- return parser
97
- rescue LoadError
98
- next
99
- end
96
+ require library
97
+ return parser
98
+ rescue LoadError
99
+ next
100
100
  end
101
- raise(NoParserError.new("No XML parser detected. If you're using Rubinius and Bundler, try adding an XML parser to your Gemfile (e.g. libxml-ruby, nokogiri, or rubysl-rexml). For more information, see https://github.com/sferik/multi_xml/issues/42."))
101
+ raise(NoParserError,
102
+ "No XML parser detected. If you're using Rubinius and Bundler, try adding an XML parser to your Gemfile (e.g. libxml-ruby, nokogiri, or rubysl-rexml). For more information, see https://github.com/sferik/multi_xml/issues/42.")
102
103
  end
103
104
 
104
105
  # Set the XML parser utilizing a symbol, string, or class.
@@ -113,11 +114,11 @@ module MultiXml # rubocop:disable ModuleLength
113
114
  case new_parser
114
115
  when String, Symbol
115
116
  require "multi_xml/parsers/#{new_parser.to_s.downcase}"
116
- @parser = MultiXml::Parsers.const_get(new_parser.to_s.split('_').collect(&:capitalize).join('').to_s)
117
+ @parser = MultiXml::Parsers.const_get(new_parser.to_s.split("_").collect(&:capitalize).join.to_s)
117
118
  when Class, Module
118
119
  @parser = new_parser
119
120
  else
120
- raise('Did not recognize your parser specification. Please specify either a symbol or a class.')
121
+ raise("Did not recognize your parser specification. Please specify either a symbol or a class.")
121
122
  end
122
123
  end
123
124
 
@@ -130,8 +131,8 @@ module MultiXml # rubocop:disable ModuleLength
130
131
  # <tt>:disallowed_types</tt> :: Types to disallow from being typecasted. Defaults to `['yaml', 'symbol']`. Use `[]` to allow all types.
131
132
  #
132
133
  # <tt>:typecast_xml_value</tt> :: If true, won't typecast values for parsed document
133
- def parse(xml, options = {}) # rubocop:disable AbcSize, CyclomaticComplexity, MethodLength, PerceivedComplexity
134
- xml ||= ''
134
+ def parse(xml, options = {}) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
135
+ xml ||= ""
135
136
 
136
137
  options = DEFAULT_OPTIONS.merge(options)
137
138
 
@@ -141,14 +142,15 @@ module MultiXml # rubocop:disable ModuleLength
141
142
 
142
143
  char = xml.getc
143
144
  return {} if char.nil?
145
+
144
146
  xml.ungetc(char)
145
147
 
146
148
  hash = undasherize_keys(parser.parse(xml) || {})
147
- hash = options[:typecast_xml_value] ? typecast_xml_value(hash, options[:disallowed_types]) : hash
149
+ hash = typecast_xml_value(hash, options[:disallowed_types]) if options[:typecast_xml_value]
148
150
  rescue DisallowedTypeError
149
151
  raise
150
- rescue parser.parse_error => error
151
- raise(ParseError, error.message, error.backtrace) # rubocop:disable RaiseArgs
152
+ rescue parser.parse_error => e
153
+ raise(ParseError, e.message, e.backtrace)
152
154
  end
153
155
  hash = symbolize_keys(hash) if options[:symbolize_keys]
154
156
  hash
@@ -156,38 +158,42 @@ module MultiXml # rubocop:disable ModuleLength
156
158
 
157
159
  # This module decorates files with the <tt>original_filename</tt>
158
160
  # and <tt>content_type</tt> methods.
159
- module FileLike #:nodoc:
161
+ module FileLike # :nodoc:
160
162
  attr_writer :original_filename, :content_type
161
163
 
162
164
  def original_filename
163
- @original_filename || 'untitled'
165
+ @original_filename || "untitled"
164
166
  end
165
167
 
166
168
  def content_type
167
- @content_type || 'application/octet-stream'
169
+ @content_type || "application/octet-stream"
168
170
  end
169
171
  end
170
172
 
171
- private
173
+ private
172
174
 
173
175
  # TODO: Add support for other encodings
174
- def parse_binary(binary, entity) #:nodoc:
175
- case entity['encoding']
176
- when 'base64'
177
- Base64.decode64(binary)
176
+ def parse_binary(binary, entity) # :nodoc:
177
+ case entity["encoding"]
178
+ when "base64"
179
+ base64_decode(binary)
178
180
  else
179
181
  binary
180
182
  end
181
183
  end
182
184
 
183
185
  def parse_file(file, entity)
184
- f = StringIO.new(Base64.decode64(file))
186
+ f = StringIO.new(base64_decode(file))
185
187
  f.extend(FileLike)
186
- f.original_filename = entity['name']
187
- f.content_type = entity['content_type']
188
+ f.original_filename = entity["name"]
189
+ f.content_type = entity["content_type"]
188
190
  f
189
191
  end
190
192
 
193
+ def base64_decode(input)
194
+ input.unpack1("m")
195
+ end
196
+
191
197
  def symbolize_keys(params)
192
198
  case params
193
199
  when Hash
@@ -204,8 +210,8 @@ module MultiXml # rubocop:disable ModuleLength
204
210
  def undasherize_keys(params)
205
211
  case params
206
212
  when Hash
207
- params.inject({}) do |hash, (key, value)|
208
- hash[key.to_s.tr('-'.freeze, '_'.freeze)] = undasherize_keys(value)
213
+ params.each_with_object({}) do |(key, value), hash|
214
+ hash[key.to_s.tr("-", "_")] = undasherize_keys(value)
209
215
  hash
210
216
  end
211
217
  when Array
@@ -215,16 +221,16 @@ module MultiXml # rubocop:disable ModuleLength
215
221
  end
216
222
  end
217
223
 
218
- def typecast_xml_value(value, disallowed_types = nil) # rubocop:disable AbcSize, CyclomaticComplexity, MethodLength, PerceivedComplexity
224
+ def typecast_xml_value(value, disallowed_types = nil) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
219
225
  disallowed_types ||= DISALLOWED_XML_TYPES
220
226
 
221
227
  case value
222
228
  when Hash
223
- if value.include?('type') && !value['type'].is_a?(Hash) && disallowed_types.include?(value['type'])
224
- raise(DisallowedTypeError.new(value['type']))
229
+ if value.include?("type") && !value["type"].is_a?(Hash) && disallowed_types.include?(value["type"])
230
+ raise(DisallowedTypeError, value["type"])
225
231
  end
226
232
 
227
- if value['type'] == 'array'
233
+ if value["type"] == "array"
228
234
 
229
235
  # this commented-out suggestion helps to avoid the multiple attribute
230
236
  # problem, but it breaks when there is only one item in the array.
@@ -239,7 +245,7 @@ module MultiXml # rubocop:disable ModuleLength
239
245
 
240
246
  # This approach ignores attribute entries that are not convertable
241
247
  # to an Array which allows attributes to be ignored.
242
- _, entries = value.detect { |k, v| k != 'type' && (v.is_a?(Array) || v.is_a?(Hash)) }
248
+ _, entries = value.detect { |k, v| k != "type" && (v.is_a?(Array) || v.is_a?(Hash)) }
243
249
 
244
250
  case entries
245
251
  when NilClass
@@ -256,10 +262,10 @@ module MultiXml # rubocop:disable ModuleLength
256
262
 
257
263
  elsif value.key?(CONTENT_ROOT)
258
264
  content = value[CONTENT_ROOT]
259
- block = PARSING[value['type']]
265
+ block = PARSING[value["type"]]
260
266
  if block
261
267
  if block.arity == 1
262
- value.delete('type') if PARSING[value['type']]
268
+ value.delete("type") if PARSING[value["type"]]
263
269
  if value.keys.size > 1
264
270
  value[CONTENT_ROOT] = block.call(content)
265
271
  value
@@ -270,31 +276,31 @@ module MultiXml # rubocop:disable ModuleLength
270
276
  block.call(content, value)
271
277
  end
272
278
  else
273
- value.keys.size > 1 ? value : content
279
+ (value.keys.size > 1) ? value : content
274
280
  end
275
- elsif value['type'] == 'string' && value['nil'] != 'true'
276
- ''
281
+ elsif value["type"] == "string" && value["nil"] != "true"
282
+ ""
277
283
  # blank or nil parsed values are represented by nil
278
- elsif value.empty? || value['nil'] == 'true'
284
+ elsif value.empty? || value["nil"] == "true"
279
285
  nil
280
286
  # If the type is the only element which makes it then
281
287
  # this still makes the value nil, except if type is
282
288
  # a XML node(where type['value'] is a Hash)
283
- elsif value['type'] && value.size == 1 && !value['type'].is_a?(Hash)
289
+ elsif value["type"] && value.size == 1 && !value["type"].is_a?(Hash)
284
290
  nil
285
291
  else
286
- xml_value = value.inject({}) do |hash, (k, v)|
292
+ xml_value = value.each_with_object({}) do |(k, v), hash|
287
293
  hash[k] = typecast_xml_value(v, disallowed_types)
288
294
  hash
289
295
  end
290
296
 
291
297
  # Turn {:files => {:file => #<StringIO>} into {:files => #<StringIO>} so it is compatible with
292
298
  # how multipart uploaded files from HTML appear
293
- xml_value['file'].is_a?(StringIO) ? xml_value['file'] : xml_value
299
+ (xml_value["file"].is_a?(StringIO)) ? xml_value["file"] : xml_value
294
300
  end
295
301
  when Array
296
302
  value.map! { |i| typecast_xml_value(i, disallowed_types) }
297
- value.length > 1 ? value : value.first
303
+ (value.length > 1) ? value : value.first
298
304
  when String
299
305
  value
300
306
  else
metadata CHANGED
@@ -1,40 +1,45 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: multi_xml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
- - Erik Michaels-Ober
8
- autorequire:
9
- bindir: bin
7
+ - Erik Berlin
8
+ autorequire:
9
+ bindir: exe
10
10
  cert_chain: []
11
- date: 2016-12-06 00:00:00.000000000 Z
11
+ date: 2024-04-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bundler
14
+ name: bigdecimal
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
20
- type: :development
19
+ version: '3.1'
20
+ type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.0'
27
- description: Provides swappable XML backends utilizing LibXML, Nokogiri, Ox, or REXML.
28
26
+ version: '3.1'
27
+ description:
28
+ email:
29
29
30
  executables: []
30
31
  extensions: []
31
32
  extra_rdoc_files: []
32
33
  files:
34
+ - ".rspec"
35
+ - ".rubocop.yml"
33
36
  - ".yardopts"
34
37
  - CHANGELOG.md
35
38
  - CONTRIBUTING.md
39
+ - Gemfile
36
40
  - LICENSE.md
37
41
  - README.md
42
+ - Rakefile
38
43
  - lib/multi_xml.rb
39
44
  - lib/multi_xml/parsers/libxml.rb
40
45
  - lib/multi_xml/parsers/libxml2_parser.rb
@@ -43,12 +48,16 @@ files:
43
48
  - lib/multi_xml/parsers/ox.rb
44
49
  - lib/multi_xml/parsers/rexml.rb
45
50
  - lib/multi_xml/version.rb
46
- - multi_xml.gemspec
47
51
  homepage: https://github.com/sferik/multi_xml
48
52
  licenses:
49
53
  - MIT
50
- metadata: {}
51
- post_install_message:
54
+ metadata:
55
+ allowed_push_host: https://rubygems.org
56
+ homepage_uri: https://github.com/sferik/multi_xml
57
+ source_code_uri: https://github.com/sferik/multi_xml
58
+ changelog_uri: https://github.com/sferik/multi_xml/blob/master/CHANGELOG.md
59
+ rubygems_mfa_required: 'true'
60
+ post_install_message:
52
61
  rdoc_options: []
53
62
  require_paths:
54
63
  - lib
@@ -56,16 +65,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
56
65
  requirements:
57
66
  - - ">="
58
67
  - !ruby/object:Gem::Version
59
- version: '0'
68
+ version: 3.1.4
60
69
  required_rubygems_version: !ruby/object:Gem::Requirement
61
70
  requirements:
62
71
  - - ">="
63
72
  - !ruby/object:Gem::Version
64
- version: 1.3.5
73
+ version: '0'
65
74
  requirements: []
66
- rubyforge_project:
67
- rubygems_version: 2.5.2
68
- signing_key:
75
+ rubygems_version: 3.5.9
76
+ signing_key:
69
77
  specification_version: 4
70
- summary: A generic swappable back-end for XML parsing
78
+ summary: Provides swappable XML backends utilizing LibXML, Nokogiri, Ox, or REXML.
71
79
  test_files: []
data/multi_xml.gemspec DELETED
@@ -1,19 +0,0 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'multi_xml/version'
5
-
6
- Gem::Specification.new do |spec|
7
- spec.add_development_dependency 'bundler', '~> 1.0'
8
- spec.author = 'Erik Michaels-Ober'
9
- spec.description = 'Provides swappable XML backends utilizing LibXML, Nokogiri, Ox, or REXML.'
10
- spec.email = '[email protected]'
11
- spec.files = %w(.yardopts CHANGELOG.md CONTRIBUTING.md LICENSE.md README.md multi_xml.gemspec) + Dir['lib/**/*.rb']
12
- spec.homepage = 'https://github.com/sferik/multi_xml'
13
- spec.licenses = ['MIT']
14
- spec.name = 'multi_xml'
15
- spec.require_paths = ['lib']
16
- spec.required_rubygems_version = '>= 1.3.5'
17
- spec.summary = 'A generic swappable back-end for XML parsing'
18
- spec.version = MultiXml::Version
19
- end
OSZAR »