nori 1.0.3 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of nori might be problematic. Click here for more details.
- data/.travis.yml +6 -4
- data/CHANGELOG.md +7 -5
- data/README.md +1 -1
- data/Rakefile +3 -7
- data/lib/nori.rb +1 -1
- data/lib/nori/parser.rb +2 -2
- data/lib/nori/parser/nokogiri.rb +6 -2
- data/lib/nori/parser/rexml.rb +2 -2
- data/lib/nori/version.rb +1 -1
- data/lib/nori/xml_utility_node.rb +17 -8
- data/nori.gemspec +1 -0
- data/spec/nori/nori_spec.rb +29 -6
- data/spec/nori/parser_spec.rb +17 -0
- metadata +90 -58
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
-
== 1.0
|
1
|
+
== 1.1.0 (2012-02-17)
|
2
2
|
|
3
|
-
*
|
4
|
-
|
5
|
-
|
3
|
+
* Improvement: Merged [pull request 9](https://github.com/rubiii/nori/pull/9) to
|
4
|
+
allow multiple configurations of Nori.
|
5
|
+
|
6
|
+
* Fix: Merged [pull request 10](https://github.com/rubiii/nori/pull/10) to handle
|
7
|
+
date/time parsing errors. Fixes a couple of similar error reports.
|
6
8
|
|
7
9
|
== 1.0.2 (2011-07-04)
|
8
10
|
|
@@ -60,7 +62,7 @@
|
|
60
62
|
|
61
63
|
== 0.2.1 (2011-05-15)
|
62
64
|
|
63
|
-
* Fix: Changed XML attributes converted to Hash keys to be prefixed with an @-sign.
|
65
|
+
* Fix: Changed XML attributes converted to Hash keys to be prefixed with an @-sign.
|
64
66
|
This avoids problems with attributes and child nodes having the same name.
|
65
67
|
|
66
68
|
<multiRef id="id1">
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Nori [![Build Status](
|
1
|
+
Nori [![Build Status](https://secure.travis-ci.org/rubiii/nori.png)](http://travis-ci.org/rubiii/nori)
|
2
2
|
====
|
3
3
|
|
4
4
|
Really simple XML parsing ripped from Crack which ripped it from Merb.
|
data/Rakefile
CHANGED
@@ -1,16 +1,12 @@
|
|
1
|
-
require "bundler"
|
2
|
-
Bundler::GemHelper.install_tasks
|
3
|
-
|
4
|
-
require "rspec/core/rake_task"
|
1
|
+
require "bundler/gem_tasks"
|
5
2
|
|
6
3
|
desc "Benchmark Nori parsers"
|
7
4
|
task :benchmark do
|
8
5
|
require "benchmark/benchmark"
|
9
6
|
end
|
10
7
|
|
11
|
-
|
12
|
-
|
13
|
-
end
|
8
|
+
require "rspec/core/rake_task"
|
9
|
+
RSpec::Core::RakeTask.new
|
14
10
|
|
15
11
|
task :default => :spec
|
16
12
|
task :test => :spec
|
data/lib/nori.rb
CHANGED
data/lib/nori/parser.rb
CHANGED
@@ -27,8 +27,8 @@ module Nori
|
|
27
27
|
|
28
28
|
# Returns the parsed +xml+ using the parser to use. Raises an +ArgumentError+
|
29
29
|
# unless the optional or default +parser+ exists.
|
30
|
-
def self.parse(xml, parser = nil)
|
31
|
-
load_parser(parser).parse
|
30
|
+
def self.parse(xml, parser = nil, nori = Nori)
|
31
|
+
load_parser(parser).parse(xml, nori)
|
32
32
|
end
|
33
33
|
|
34
34
|
private
|
data/lib/nori/parser/nokogiri.rb
CHANGED
@@ -9,13 +9,14 @@ module Nori
|
|
9
9
|
module Nokogiri
|
10
10
|
|
11
11
|
class Document < ::Nokogiri::XML::SAX::Document
|
12
|
+
attr_accessor :nori
|
12
13
|
|
13
14
|
def stack
|
14
15
|
@stack ||= []
|
15
16
|
end
|
16
17
|
|
17
18
|
def start_element(name, attrs = [])
|
18
|
-
stack.push Nori::XMLUtilityNode.new(name, Hash[*attrs.flatten])
|
19
|
+
stack.push Nori::XMLUtilityNode.new(nori, name, Hash[*attrs.flatten])
|
19
20
|
end
|
20
21
|
|
21
22
|
def end_element(name)
|
@@ -33,8 +34,11 @@ module Nori
|
|
33
34
|
|
34
35
|
end
|
35
36
|
|
36
|
-
def self.parse(xml)
|
37
|
+
def self.parse(xml, nori)
|
38
|
+
return {} if xml.strip.empty?
|
39
|
+
|
37
40
|
document = Document.new
|
41
|
+
document.nori = nori
|
38
42
|
parser = ::Nokogiri::XML::SAX::Parser.new document
|
39
43
|
parser.parse xml
|
40
44
|
document.stack.length > 0 ? document.stack.pop.to_hash : {}
|
data/lib/nori/parser/rexml.rb
CHANGED
@@ -8,7 +8,7 @@ module Nori
|
|
8
8
|
# REXML pull parser.
|
9
9
|
module REXML
|
10
10
|
|
11
|
-
def self.parse(xml)
|
11
|
+
def self.parse(xml, nori)
|
12
12
|
stack = []
|
13
13
|
parser = ::REXML::Parsers::BaseParser.new(xml)
|
14
14
|
|
@@ -20,7 +20,7 @@ module Nori
|
|
20
20
|
when :end_doctype, :start_doctype
|
21
21
|
# do nothing
|
22
22
|
when :start_element
|
23
|
-
stack.push Nori::XMLUtilityNode.new(event[1], event[2])
|
23
|
+
stack.push Nori::XMLUtilityNode.new(nori, event[1], event[2])
|
24
24
|
when :end_element
|
25
25
|
if stack.size > 1
|
26
26
|
temp = stack.pop
|
data/lib/nori/version.rb
CHANGED
@@ -52,20 +52,23 @@ module Nori
|
|
52
52
|
self.typecasts["decimal"] = lambda { |v| v.nil? ? nil : BigDecimal(v.to_s) }
|
53
53
|
self.typecasts["double"] = lambda { |v| v.nil? ? nil : v.to_f }
|
54
54
|
self.typecasts["float"] = lambda { |v| v.nil? ? nil : v.to_f }
|
55
|
+
self.typecasts["symbol"] = lambda { |v| v.nil? ? nil : v.to_sym }
|
55
56
|
self.typecasts["string"] = lambda { |v| v.to_s }
|
57
|
+
self.typecasts["yaml"] = lambda { |v| v.nil? ? nil : YAML.load(v) }
|
56
58
|
self.typecasts["base64Binary"] = lambda { |v| v.unpack('m').first }
|
57
59
|
|
58
60
|
self.available_typecasts = self.typecasts.keys
|
59
61
|
|
60
|
-
def initialize(name, normalized_attributes = {})
|
62
|
+
def initialize(nori, name, normalized_attributes = {})
|
61
63
|
# unnormalize attribute values
|
62
64
|
attributes = Hash[* normalized_attributes.map do |key, value|
|
63
65
|
[ key, unnormalize_xml_entities(value) ]
|
64
66
|
end.flatten]
|
65
67
|
|
68
|
+
@nori = nori
|
66
69
|
@name = name.tr("-", "_")
|
67
|
-
@name = @name.split(":").last if
|
68
|
-
@name =
|
70
|
+
@name = @name.split(":").last if @nori.strip_namespaces?
|
71
|
+
@name = @nori.convert_tag(@name) if @nori.convert_tags?
|
69
72
|
|
70
73
|
# leave the type alone if we don't know what it is
|
71
74
|
@type = self.class.available_typecasts.include?(attributes["type"]) ? attributes.delete("type") : attributes["type"]
|
@@ -92,7 +95,7 @@ module Nori
|
|
92
95
|
end
|
93
96
|
|
94
97
|
def prefixed_attribute_name(attribute)
|
95
|
-
|
98
|
+
@nori.convert_tags? ? @nori.convert_tag(attribute) : attribute
|
96
99
|
end
|
97
100
|
|
98
101
|
def add_node(node)
|
@@ -110,7 +113,7 @@ module Nori
|
|
110
113
|
|
111
114
|
if @text
|
112
115
|
t = typecast_value unnormalize_xml_entities(inner_html)
|
113
|
-
t = advanced_typecasting(t) if t.is_a?(String) &&
|
116
|
+
t = advanced_typecasting(t) if t.is_a?(String) && @nori.advanced_typecasting?
|
114
117
|
|
115
118
|
if t.is_a?(String)
|
116
119
|
t = StringWithAttributes.new(t)
|
@@ -191,9 +194,9 @@ module Nori
|
|
191
194
|
case split.first
|
192
195
|
when "true" then true
|
193
196
|
when "false" then false
|
194
|
-
when XS_DATE_TIME then DateTime.parse(
|
195
|
-
when XS_DATE then Date.parse(
|
196
|
-
when XS_TIME then Time.parse(
|
197
|
+
when XS_DATE_TIME then try_to_convert(value) {|x| DateTime.parse(x)}
|
198
|
+
when XS_DATE then try_to_convert(value) {|x| Date.parse(x)}
|
199
|
+
when XS_TIME then try_to_convert(value) {|x| Time.parse(x)}
|
197
200
|
else value
|
198
201
|
end
|
199
202
|
end
|
@@ -227,6 +230,12 @@ module Nori
|
|
227
230
|
def unnormalize_xml_entities value
|
228
231
|
REXML::Text.unnormalize(value)
|
229
232
|
end
|
233
|
+
|
234
|
+
def try_to_convert(value, &block)
|
235
|
+
block.call(value)
|
236
|
+
rescue ArgumentError
|
237
|
+
value
|
238
|
+
end
|
230
239
|
end
|
231
240
|
|
232
241
|
end
|
data/nori.gemspec
CHANGED
@@ -13,6 +13,7 @@ Gem::Specification.new do |s|
|
|
13
13
|
|
14
14
|
s.rubyforge_project = "nori"
|
15
15
|
|
16
|
+
s.add_development_dependency "rake", "~> 0.8.7"
|
16
17
|
s.add_development_dependency "nokogiri", ">= 1.4.0"
|
17
18
|
s.add_development_dependency "rspec", "~> 2.5.0"
|
18
19
|
s.add_development_dependency "autotest"
|
data/spec/nori/nori_spec.rb
CHANGED
@@ -154,6 +154,12 @@ describe Nori do
|
|
154
154
|
parse("<value>1955-04-18T11:22:33-05:00 is a dateTime</value>")["value"].should ==
|
155
155
|
"1955-04-18T11:22:33-05:00 is a dateTime"
|
156
156
|
end
|
157
|
+
|
158
|
+
["00-00-00", "0000-00-00", "0000-00-00T00:00:00", "0569-23-0141", "DS2001-19-1312654773", "e6:53:01:00:ce:b4:06"].each do |date_string|
|
159
|
+
it "should not transform a String like '#{date_string}' to date or time" do
|
160
|
+
parse("<value>#{date_string}</value>")["value"].should == date_string
|
161
|
+
end
|
162
|
+
end
|
157
163
|
end
|
158
164
|
|
159
165
|
context "Parsing xml with text and attributes" do
|
@@ -367,8 +373,7 @@ describe Nori do
|
|
367
373
|
'approved' => nil,
|
368
374
|
'written_on' => nil,
|
369
375
|
'viewed_at' => nil,
|
370
|
-
|
371
|
-
'content' => { "@type" => "yaml" },
|
376
|
+
'content' => nil,
|
372
377
|
'parent_id' => nil,
|
373
378
|
'nil_true' => nil,
|
374
379
|
'namespaced' => nil
|
@@ -387,7 +392,7 @@ describe Nori do
|
|
387
392
|
<replies-close-in type="integer">2592000000</replies-close-in>
|
388
393
|
<written-on type="date">2003-07-16</written-on>
|
389
394
|
<viewed-at type="datetime">2003-07-16T09:28:00+0000</viewed-at>
|
390
|
-
<content type="yaml">--- \n1: should be an integer\n:message: Have a nice day\narray: \n- should-have-dashes: true\n should_have_underscores: true</content>
|
395
|
+
<content type="yaml">--- \n1: should be an integer\n:message: Have a nice day\narray: \n- should-have-dashes: true\n should_have_underscores: true\n</content>
|
391
396
|
<author-email-address>david@loudthinking.com</author-email-address>
|
392
397
|
<parent-id></parent-id>
|
393
398
|
<ad-revenue type="decimal">1.5</ad-revenue>
|
@@ -408,13 +413,12 @@ describe Nori do
|
|
408
413
|
# Changed this line where the key is :message. The yaml specifies this as a symbol, and who am I to change what you specify
|
409
414
|
# The line in ActiveSupport is
|
410
415
|
# 'content' => { 'message' => "Have a nice day", 1 => "should be an integer", "array" => [{ "should-have-dashes" => true, "should_have_underscores" => true }] },
|
411
|
-
'content' =>
|
416
|
+
'content' => { :message => "Have a nice day", 1 => "should be an integer", "array" => [{ "should-have-dashes" => true, "should_have_underscores" => true }] },
|
412
417
|
'author_email_address' => "david@loudthinking.com",
|
413
418
|
'parent_id' => nil,
|
414
419
|
'ad_revenue' => BigDecimal("1.50"),
|
415
420
|
'optimum_viewing_angle' => 135.0,
|
416
|
-
|
417
|
-
'resident' => "yes"
|
421
|
+
'resident' => :yes
|
418
422
|
}
|
419
423
|
|
420
424
|
parse(topic_xml)["topic"].each do |k,v|
|
@@ -634,6 +638,25 @@ describe Nori do
|
|
634
638
|
end
|
635
639
|
|
636
640
|
end
|
641
|
+
|
642
|
+
describe "using different nori" do
|
643
|
+
let(:parser) { parser }
|
644
|
+
let(:different_nori) do
|
645
|
+
module DifferentNori
|
646
|
+
extend Nori
|
647
|
+
end
|
648
|
+
DifferentNori.configure do |config|
|
649
|
+
config.convert_tags_to { |tag| tag.upcase }
|
650
|
+
end
|
651
|
+
DifferentNori
|
652
|
+
end
|
653
|
+
|
654
|
+
it "should transform with different nori" do
|
655
|
+
xml = "<SomeThing>xml</SomeThing>"
|
656
|
+
parse(xml).should == { "SomeThing" => "xml" }
|
657
|
+
different_nori.parse(xml, parser).should == { "SOMETHING" => "xml" }
|
658
|
+
end
|
659
|
+
end
|
637
660
|
end
|
638
661
|
|
639
662
|
def parse(xml)
|
data/spec/nori/parser_spec.rb
CHANGED
@@ -34,4 +34,21 @@ describe Nori::Parser do
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
+
describe ".parse with different nori" do
|
38
|
+
let(:other_nori) do
|
39
|
+
module OtherNori
|
40
|
+
extend Nori
|
41
|
+
end
|
42
|
+
OtherNori.configure do |config|
|
43
|
+
config.convert_tags_to { |tag| tag.upcase }
|
44
|
+
end
|
45
|
+
OtherNori
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should load the parser to use and parse the given xml" do
|
49
|
+
parser.parse("<SomeThing>xml</SomeThing>").should == { "SomeThing" => "xml" }
|
50
|
+
parser.parse("<SomeThing>xml</SomeThing>", nil, other_nori).should == { "SOMETHING" => "xml" }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
37
54
|
end
|
metadata
CHANGED
@@ -1,72 +1,95 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: nori
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 1.1.0
|
6
11
|
platform: ruby
|
7
|
-
authors:
|
12
|
+
authors:
|
8
13
|
- Daniel Harrington
|
9
14
|
- John Nunemaker
|
10
15
|
- Wynn Netherland
|
11
16
|
autorequire:
|
12
17
|
bindir: bin
|
13
18
|
cert_chain: []
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
requirement: !ruby/object:Gem::Requirement
|
19
|
-
none: false
|
20
|
-
requirements:
|
21
|
-
- - ! '>='
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 1.4.0
|
24
|
-
type: :development
|
19
|
+
|
20
|
+
date: 2012-02-17 00:00:00 Z
|
21
|
+
dependencies:
|
22
|
+
- !ruby/object:Gem::Dependency
|
25
23
|
prerelease: false
|
26
|
-
|
27
|
-
|
28
|
-
requirements:
|
29
|
-
- - ! '>='
|
30
|
-
- !ruby/object:Gem::Version
|
31
|
-
version: 1.4.0
|
32
|
-
- !ruby/object:Gem::Dependency
|
33
|
-
name: rspec
|
34
|
-
requirement: !ruby/object:Gem::Requirement
|
24
|
+
type: :development
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
35
26
|
none: false
|
36
|
-
requirements:
|
27
|
+
requirements:
|
37
28
|
- - ~>
|
38
|
-
- !ruby/object:Gem::Version
|
39
|
-
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 49
|
31
|
+
segments:
|
32
|
+
- 0
|
33
|
+
- 8
|
34
|
+
- 7
|
35
|
+
version: 0.8.7
|
36
|
+
version_requirements: *id001
|
37
|
+
name: rake
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
prerelease: false
|
40
40
|
type: :development
|
41
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
hash: 7
|
47
|
+
segments:
|
48
|
+
- 1
|
49
|
+
- 4
|
50
|
+
- 0
|
51
|
+
version: 1.4.0
|
52
|
+
version_requirements: *id002
|
53
|
+
name: nokogiri
|
54
|
+
- !ruby/object:Gem::Dependency
|
41
55
|
prerelease: false
|
42
|
-
|
56
|
+
type: :development
|
57
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
43
58
|
none: false
|
44
|
-
requirements:
|
59
|
+
requirements:
|
45
60
|
- - ~>
|
46
|
-
- !ruby/object:Gem::Version
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
hash: 27
|
63
|
+
segments:
|
64
|
+
- 2
|
65
|
+
- 5
|
66
|
+
- 0
|
47
67
|
version: 2.5.0
|
48
|
-
|
49
|
-
name:
|
50
|
-
|
51
|
-
none: false
|
52
|
-
requirements:
|
53
|
-
- - ! '>='
|
54
|
-
- !ruby/object:Gem::Version
|
55
|
-
version: '0'
|
56
|
-
type: :development
|
68
|
+
version_requirements: *id003
|
69
|
+
name: rspec
|
70
|
+
- !ruby/object:Gem::Dependency
|
57
71
|
prerelease: false
|
58
|
-
|
72
|
+
type: :development
|
73
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
59
74
|
none: false
|
60
|
-
requirements:
|
61
|
-
- -
|
62
|
-
- !ruby/object:Gem::Version
|
63
|
-
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
hash: 3
|
79
|
+
segments:
|
80
|
+
- 0
|
81
|
+
version: "0"
|
82
|
+
version_requirements: *id004
|
83
|
+
name: autotest
|
64
84
|
description: XML to Hash translator
|
65
85
|
email: me@rubiii.com
|
66
86
|
executables: []
|
87
|
+
|
67
88
|
extensions: []
|
89
|
+
|
68
90
|
extra_rdoc_files: []
|
69
|
-
|
91
|
+
|
92
|
+
files:
|
70
93
|
- .gitignore
|
71
94
|
- .rspec
|
72
95
|
- .travis.yml
|
@@ -98,29 +121,38 @@ files:
|
|
98
121
|
- spec/spec_helper.rb
|
99
122
|
homepage: http://github.com/rubiii/nori
|
100
123
|
licenses: []
|
124
|
+
|
101
125
|
post_install_message:
|
102
126
|
rdoc_options: []
|
103
|
-
|
127
|
+
|
128
|
+
require_paths:
|
104
129
|
- lib
|
105
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
130
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
131
|
none: false
|
107
|
-
requirements:
|
108
|
-
- -
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
|
111
|
-
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
hash: 3
|
136
|
+
segments:
|
137
|
+
- 0
|
138
|
+
version: "0"
|
139
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
140
|
none: false
|
113
|
-
requirements:
|
114
|
-
- -
|
115
|
-
- !ruby/object:Gem::Version
|
116
|
-
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
hash: 3
|
145
|
+
segments:
|
146
|
+
- 0
|
147
|
+
version: "0"
|
117
148
|
requirements: []
|
149
|
+
|
118
150
|
rubyforge_project: nori
|
119
|
-
rubygems_version: 1.8.
|
151
|
+
rubygems_version: 1.8.10
|
120
152
|
signing_key:
|
121
153
|
specification_version: 3
|
122
154
|
summary: XML to Hash translator
|
123
|
-
test_files:
|
155
|
+
test_files:
|
124
156
|
- spec/nori/core_ext/hash_spec.rb
|
125
157
|
- spec/nori/core_ext/object_spec.rb
|
126
158
|
- spec/nori/core_ext/string_spec.rb
|