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