saxy 0.7.0 → 0.7.1
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 +4 -4
- data/.travis.yml +1 -0
- data/CHANGELOG.md +5 -0
- data/README.md +8 -0
- data/lib/saxy/element.rb +13 -7
- data/lib/saxy/parser.rb +9 -3
- data/lib/saxy/version.rb +1 -1
- data/spec/fixtures/invalid.xml +1 -1
- data/spec/saxy/element_spec.rb +6 -4
- data/spec/saxy/parser_spec.rb +20 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 52a8b74342fe631ae2787bd38fedcb3600b24730
|
4
|
+
data.tar.gz: 37ef8a7e143494b48ba13c3d7470c84e459d0bf7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 468d1551a3fdafc0c0b37cdffb5482f1ecd5cf2fac2c8f63b23c7d75dc38c1d13b47ac8a7d195b8031251d62a5ea13492674cf418f25cf732d30e073a8f99f9b
|
7
|
+
data.tar.gz: d026bfaa8643b1eeb12ce00eecc13e4f1d27e531308706e14d05f1a9bc2d22755a5e2479482d5024ce298732373ea62498314d083fe4a2fa2aa8e5da3399c6a9
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# Saxy Changelog
|
2
2
|
|
3
|
+
## 0.7.1
|
4
|
+
|
5
|
+
* Fixed whitespace stripping from elements' contents, now only leading and trailing whitespace is stripped (reported by @wzcolon, thanks!).
|
6
|
+
* Added `error_handler` option to make it possible to handle errors on-the-fly instead of raising them.
|
7
|
+
|
3
8
|
## 0.7.0
|
4
9
|
|
5
10
|
* [BREAKING] Yielded hashes now have strings as keys instead of symbols (performance and security fix).
|
data/README.md
CHANGED
@@ -64,6 +64,14 @@ end
|
|
64
64
|
* `encoding` - Forces the parser to work in given encoding
|
65
65
|
* `recovery` - Should this parser recover from structural errors? It will not stop processing file on structural errors if set to `true`.
|
66
66
|
* `replace_entities` - Should this parser replace entities? `&` will get converted to `&` if set to `true`.
|
67
|
+
* `error_handler` - If set to a callable, parser will call it with any error it encounters instead of raising exceptions.
|
68
|
+
|
69
|
+
Combination of `error_handler` and `recovery` options allows for continued processing when encountering recoverable errors (e.g. unescaped [predefined entities](https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Predefined_entities_in_XML)).
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
error_handler = proc { |e| $stderr.puts "#{e.message} at line #{e.context.line}, column #{e.context.column}." }
|
73
|
+
Saxy.parse(path_or_io, object_tag, error_handler: error_handler, recovery: true) { ... }
|
74
|
+
```
|
67
75
|
|
68
76
|
## Example
|
69
77
|
|
data/lib/saxy/element.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Saxy
|
2
2
|
class Element
|
3
|
-
attr_reader :attributes
|
3
|
+
attr_reader :attributes
|
4
4
|
|
5
5
|
def initialize
|
6
6
|
@attributes = {}
|
@@ -9,23 +9,30 @@ module Saxy
|
|
9
9
|
|
10
10
|
def set_attribute(name, value)
|
11
11
|
name = attribute_name(name)
|
12
|
+
|
12
13
|
attributes[name] ||= []
|
13
14
|
attributes[name] << value
|
14
15
|
end
|
15
16
|
|
16
17
|
def append_value(string)
|
17
|
-
|
18
|
+
if @value || !string.strip.empty?
|
18
19
|
@value ||= ""
|
19
20
|
@value << string
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
24
|
+
def value
|
25
|
+
@value && @value.strip
|
26
|
+
end
|
27
|
+
|
23
28
|
def to_h
|
24
29
|
return value unless attributes.any?
|
30
|
+
|
25
31
|
data = attributes.reduce({}) do |memo, (name, value)|
|
26
32
|
memo[name] = value.size == 1 ? value.first : value
|
27
33
|
memo
|
28
34
|
end
|
35
|
+
|
29
36
|
data["contents"] = value
|
30
37
|
data
|
31
38
|
end
|
@@ -37,12 +44,11 @@ module Saxy
|
|
37
44
|
private
|
38
45
|
|
39
46
|
def underscore(word)
|
40
|
-
word = word.dup
|
41
|
-
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
42
|
-
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
43
|
-
word.tr!("-", "_")
|
44
|
-
word.downcase!
|
45
47
|
word
|
48
|
+
.gsub(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
49
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
50
|
+
.tr("-", "_")
|
51
|
+
.downcase
|
46
52
|
end
|
47
53
|
end
|
48
54
|
end
|
data/lib/saxy/parser.rb
CHANGED
@@ -41,6 +41,7 @@ module Saxy
|
|
41
41
|
|
42
42
|
def end_element(tag)
|
43
43
|
tags.pop
|
44
|
+
|
44
45
|
if element = elements.pop
|
45
46
|
object = element.to_h
|
46
47
|
|
@@ -61,7 +62,13 @@ module Saxy
|
|
61
62
|
end
|
62
63
|
|
63
64
|
def error(message)
|
64
|
-
|
65
|
+
error = ParsingError.new(message, context)
|
66
|
+
|
67
|
+
if options[:error_handler].respond_to?(:call)
|
68
|
+
options[:error_handler].call(error)
|
69
|
+
else
|
70
|
+
raise error
|
71
|
+
end
|
65
72
|
end
|
66
73
|
|
67
74
|
def current_element
|
@@ -73,8 +80,7 @@ module Saxy
|
|
73
80
|
|
74
81
|
@callback = blk
|
75
82
|
|
76
|
-
args
|
77
|
-
|
83
|
+
args = [self, options[:encoding]].compact
|
78
84
|
parser = Nokogiri::XML::SAX::Parser.new(*args)
|
79
85
|
|
80
86
|
if @object.respond_to?(:read) && @object.respond_to?(:close)
|
data/lib/saxy/version.rb
CHANGED
data/spec/fixtures/invalid.xml
CHANGED
data/spec/saxy/element_spec.rb
CHANGED
@@ -8,10 +8,12 @@ describe Saxy::Element do
|
|
8
8
|
expect(element.value).to be_nil
|
9
9
|
end
|
10
10
|
|
11
|
-
it "should
|
12
|
-
element.append_value("
|
13
|
-
element.append_value("
|
14
|
-
|
11
|
+
it "should strip leading and trailing whitespace" do
|
12
|
+
element.append_value(" one two ")
|
13
|
+
element.append_value("&")
|
14
|
+
element.append_value(" three\nfour")
|
15
|
+
element.append_value("\t\t")
|
16
|
+
expect(element.value).to eq("one two & three\nfour")
|
15
17
|
end
|
16
18
|
|
17
19
|
it "should dump as string when no attributes are set" do
|
data/spec/saxy/parser_spec.rb
CHANGED
@@ -4,7 +4,6 @@ describe Saxy::Parser do
|
|
4
4
|
include FixturesHelper
|
5
5
|
|
6
6
|
let(:parser) { Saxy::Parser.new(fixture_file("webstore.xml"), "product") }
|
7
|
-
let(:invalid_parser) { Saxy::Parser.new(fixture_file("invalid.xml"), "product") }
|
8
7
|
let(:file_io) { File.new(fixture_file("webstore.xml")) }
|
9
8
|
let(:io_like) { IOLike.new(file_io) }
|
10
9
|
|
@@ -165,12 +164,26 @@ describe Saxy::Parser do
|
|
165
164
|
end
|
166
165
|
end
|
167
166
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
expect
|
173
|
-
|
167
|
+
context "when error handler is not set" do
|
168
|
+
let(:parser) { Saxy::Parser.new(fixture_file("invalid.xml"), "product") }
|
169
|
+
|
170
|
+
it "should raise Saxy::ParsingError on error" do
|
171
|
+
expect { parser.each.to_a }.to raise_error { |error|
|
172
|
+
expect(error).to be_a(Saxy::ParsingError)
|
173
|
+
expect(error.message).to match(/xmlParseEntityRef: no name/)
|
174
|
+
expect(error.context).to be_a(Nokogiri::XML::SAX::ParserContext)
|
175
|
+
}
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
context "when error handler is set" do
|
180
|
+
let(:handler) { proc { |error| error } }
|
181
|
+
let(:parser) { Saxy::Parser.new(fixture_file("invalid.xml"), "product", error_handler: handler) }
|
182
|
+
|
183
|
+
it "should call error handler passing Saxy::ParsingError instance" do
|
184
|
+
expect(handler).to receive(:call).with(Saxy::ParsingError)
|
185
|
+
parser.each.to_a
|
186
|
+
end
|
174
187
|
end
|
175
188
|
|
176
189
|
it "should return Enumerator when calling #each without a block" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: saxy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michał Szajbe
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-04-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|