flexparser 1.0.2 → 1.0.3
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/.rubocop.yml +4 -1
- data/.travis.yml +13 -1
- data/CHANGELOG.md +15 -0
- data/README.md +32 -26
- data/flexparser.gemspec +16 -12
- data/lib/flexparser/class_methods.rb +5 -0
- data/lib/flexparser/collection_parser.rb +6 -1
- data/lib/flexparser/fragment.rb +3 -0
- data/lib/flexparser/fragment_builder.rb +6 -0
- data/lib/flexparser/version.rb +1 -1
- metadata +36 -23
- data/.rubocop_todo.yml +0 -22
- data/test.xml +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4ba7b7c2ab1a7b1dc24734ad511d993f2066f55
|
4
|
+
data.tar.gz: 1fb2f8ab41e9de46bc75a5ac5f3a7353187ed64e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 168e4a55291b552671ab2d3cd37721f6b60eb8e74c6f769a0c8628038707acd57a7ce4df05aa34d58d4041b94f904f92786a800066d1cf61497c80c1f73f0f5a
|
7
|
+
data.tar.gz: 24aca6ac3b60723efad772664d11ed20c13401f003b59517604b5cf5c9ddf3bc52e9884e999bb3409204a785ad7cfc197c5790a7e9c33a0ff4581a07b5a05cae
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
sudo: false
|
2
2
|
language: ruby
|
3
3
|
rvm:
|
4
|
+
- 2.2.4
|
5
|
+
- 2.2.1
|
6
|
+
- 2.3.0
|
4
7
|
- 2.3.3
|
5
|
-
|
8
|
+
- 2.4.3
|
9
|
+
- 2.5.0
|
10
|
+
- jruby
|
11
|
+
before_install: gem install bundler flay rubocop
|
12
|
+
install:
|
13
|
+
- bundle install --retry=3 --with development
|
14
|
+
script:
|
15
|
+
- bundle exec rake test
|
16
|
+
- bundle exec rubocop
|
17
|
+
- bundle exec flay
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
<!--
|
2
|
+
|
3
|
+
// Please add your own contribution below inside the Master section, no need to
|
4
|
+
// set a version number, that happens during a deploy.
|
5
|
+
//
|
6
|
+
// These docs are aimed at users rather than danger developers, so please limit technical
|
7
|
+
// terminology in here.
|
8
|
+
|
9
|
+
-->
|
10
|
+
|
11
|
+
## master
|
12
|
+
|
13
|
+
* Added some more documentation to Classmethods#parse.
|
14
|
+
* Added minimum required ruby version.
|
15
|
+
* Updated dependencies.
|
data/README.md
CHANGED
@@ -1,17 +1,22 @@
|
|
1
|
+
|
1
2
|
# Flexparser
|
2
|
-
|
3
|
+
[](https://travis-ci.org/lokalportal/flexparser)
|
4
|
+
`Flexparser`
|
5
|
+
|
6
|
+
Provides an easy to use DSL for flexible, robust xml parsers. The goal of flexparser is to be able to write **One Parser to parse them all**.
|
3
7
|
|
4
8
|
## Installation
|
5
9
|
|
6
10
|
Add this line to your application's Gemfile:
|
7
11
|
|
8
12
|
```ruby
|
9
|
-
gem 'flexparser'
|
13
|
+
gem 'flexparser'
|
10
14
|
```
|
11
15
|
|
12
|
-
|
13
|
-
|
14
|
-
|
16
|
+
Or simply
|
17
|
+
```shell
|
18
|
+
gem install flexparser
|
19
|
+
```
|
15
20
|
|
16
21
|
## Usage
|
17
22
|
#### Basics:
|
@@ -58,7 +63,7 @@ work.story #=> ['The Call of Cthulhu', 'Dagon', 'The Nameless City']
|
|
58
63
|
```
|
59
64
|
|
60
65
|
#### Nested Parsers
|
61
|
-
Sometimes you want more than to just
|
66
|
+
Sometimes you want more than to just extract a String. This way you can make your parser return complex Objects and nest parsers as deep as you like.
|
62
67
|
```ruby
|
63
68
|
library = "
|
64
69
|
<book>
|
@@ -119,6 +124,24 @@ class UniParser
|
|
119
124
|
property %w[image picture @img media:image], name: 'visual', type: URI, collection: true
|
120
125
|
end
|
121
126
|
```
|
127
|
+
#### Defining a parser with a block
|
128
|
+
When defining nested parsers, you would use a block. Like this:
|
129
|
+
```ruby
|
130
|
+
class ParserClass
|
131
|
+
include Flexparser
|
132
|
+
|
133
|
+
property 'story', collection: true do
|
134
|
+
property 'author'
|
135
|
+
property 'title'
|
136
|
+
end
|
137
|
+
end
|
138
|
+
```
|
139
|
+
When passing a block to a parser definition, a new class is created that basically looks like this:
|
140
|
+
```ruby
|
141
|
+
Class.new { include Flexparser }
|
142
|
+
```
|
143
|
+
The block is then `class_eval`ed on this anonymous class. Thats gives you a lot of flexibility in definen your parsers.
|
144
|
+
|
122
145
|
### Configuration
|
123
146
|
You can configure Flexparser by using a block (for example in an initializer) like so:
|
124
147
|
```ruby
|
@@ -129,7 +152,7 @@ end
|
|
129
152
|
At time of writing there are two Options:
|
130
153
|
|
131
154
|
#### `explicit_property_naming`
|
132
|
-
**Default
|
155
|
+
**Default:** `true`
|
133
156
|
If this is `true` you need to specify a `:name` for your `property` everytime there is more than one tag in your tag-list.
|
134
157
|
Example:
|
135
158
|
```ruby
|
@@ -153,7 +176,7 @@ class SomeParser
|
|
153
176
|
property 'inventory'
|
154
177
|
end
|
155
178
|
|
156
|
-
xml =
|
179
|
+
xml = '<inventory xmlns="www.my-inventory.com">james</inventory>'
|
157
180
|
|
158
181
|
# The inventory can't be found because it is namespaced.
|
159
182
|
SomeParser.parse(xml).inventory #=> nil :(
|
@@ -163,7 +186,7 @@ class SomeBetterParser
|
|
163
186
|
property 'inventory'
|
164
187
|
end
|
165
188
|
|
166
|
-
xml =
|
189
|
+
xml = '<inventory xmlns="www.my-inventory.com">james</inventory>'
|
167
190
|
|
168
191
|
# The inventory can be found because we don't care.
|
169
192
|
SomeParser.parse(xml).inventory #=> 'james'
|
@@ -181,20 +204,3 @@ The `Flexparser` module defines certain class methods. Most importantly `propert
|
|
181
204
|
The Parsers use an instance of `Flexparser::XPaths` to handle the array of tags that they are passed.
|
182
205
|
When everything is setup (i.e. the class is loaded), you can call `::parse` on your MainClass and pass it an XML string. At this point the MainClass instantiates itself and the `TagParser`s and `CollectionParser`s extract a value from the xml, that is then assigned to the newly created MainClass instance.
|
183
206
|
|
184
|
-
#### Defining a parser with a block
|
185
|
-
When defining nested parsers, you would use a block. Like this:
|
186
|
-
```ruby
|
187
|
-
class ParserClass
|
188
|
-
include Flexparser
|
189
|
-
|
190
|
-
property 'story', collection: true do
|
191
|
-
property 'author'
|
192
|
-
property 'title'
|
193
|
-
end
|
194
|
-
end
|
195
|
-
```
|
196
|
-
When passing a block to a parser definition, a new class is created that basically looks like this:
|
197
|
-
```ruby
|
198
|
-
Class.new { include Flexparser }
|
199
|
-
```
|
200
|
-
The block is then `class_eval`ed on this anonymous class. Thats gives you a lot of flexibility in definen your parsers.
|
data/flexparser.gemspec
CHANGED
@@ -5,14 +5,17 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
5
|
require 'flexparser/version'
|
6
6
|
|
7
7
|
Gem::Specification.new do |spec|
|
8
|
-
spec.name
|
9
|
-
spec.version
|
10
|
-
spec.authors
|
11
|
-
spec.email
|
12
|
-
spec.licenses
|
13
|
-
spec.homepage
|
14
|
-
spec.summary
|
15
|
-
spec.
|
8
|
+
spec.name = 'flexparser'
|
9
|
+
spec.version = Flexparser::VERSION
|
10
|
+
spec.authors = ['Paul Martensen']
|
11
|
+
spec.email = ['paul.martensen@gmx.de']
|
12
|
+
spec.licenses = ['GPL-3.0']
|
13
|
+
spec.homepage = 'https://github.com/lokalportal/flexparser'
|
14
|
+
spec.summary = 'A xml-parser dsl'
|
15
|
+
spec.required_ruby_version = '>= 2.1.0'
|
16
|
+
spec.description = <<-DESC
|
17
|
+
A flexible and robust parser-dsl which is escpecially good for data-normalization.
|
18
|
+
DESC
|
16
19
|
|
17
20
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
21
|
f.match(%r{^(test|spec|features)/})
|
@@ -21,12 +24,13 @@ Gem::Specification.new do |spec|
|
|
21
24
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
25
|
spec.require_paths = ['lib']
|
23
26
|
|
24
|
-
spec.add_dependency 'nokogiri', '~> 1
|
25
|
-
spec.add_dependency 'xpath', '~> 2
|
27
|
+
spec.add_dependency 'nokogiri', '~> 1'
|
28
|
+
spec.add_dependency 'xpath', '~> 2'
|
26
29
|
spec.add_development_dependency 'guard', '~> 2.14'
|
27
30
|
spec.add_development_dependency 'guard-minitest', '~> 2.4'
|
28
|
-
spec.add_development_dependency 'pry-byebug', '~> 3.4'
|
29
31
|
spec.add_development_dependency 'bundler', '~> 1.13'
|
30
32
|
spec.add_development_dependency 'rake', '~> 10.0'
|
31
|
-
spec.add_development_dependency 'minitest', '~> 5
|
33
|
+
spec.add_development_dependency 'minitest', '~> 5'
|
34
|
+
spec.add_development_dependency 'rubocop', '~> 0.52'
|
35
|
+
spec.add_development_dependency 'flay', '~> 2'
|
32
36
|
end
|
@@ -6,6 +6,11 @@ module Flexparser
|
|
6
6
|
#
|
7
7
|
# Applies the previously set up property-structure to the given xml
|
8
8
|
# and returns Instances of the including Class.
|
9
|
+
# @param xml [String] The xml string to be parsed by this parser.
|
10
|
+
# @param _options [Hash] an (as of yet) unused options hash.
|
11
|
+
# Swallowing options here keeps compatability with HappyMapper.
|
12
|
+
# @return [Object] An object of `self.class` that is initialized
|
13
|
+
# with the extracted values from its subparsers.
|
9
14
|
#
|
10
15
|
def parse(xml, _options = {})
|
11
16
|
return if parsers.empty?
|
@@ -1,13 +1,18 @@
|
|
1
1
|
module Flexparser
|
2
2
|
#
|
3
3
|
# A Parser similar to the TagParser but intendet for a collection
|
4
|
-
# of
|
4
|
+
# of properties.
|
5
5
|
# @param sub_parser [Wrench] all CollectionParsers need a subparser to
|
6
6
|
# deal with the content of the nodes parsed. This should ideally be
|
7
7
|
# a class that includes Spigots::Wrench and can parse the fragment it
|
8
8
|
# is dealt.
|
9
9
|
#
|
10
10
|
class CollectionParser < TagParser
|
11
|
+
#
|
12
|
+
# @param doc [Nokogiri::Node] a node that can be accessed through xpath
|
13
|
+
# @return [Array<Object>] An array of String if no type was specified,
|
14
|
+
# otherwise the type will try to parse the string using ::parse
|
15
|
+
#
|
11
16
|
def parse(doc)
|
12
17
|
content(doc).map do |n|
|
13
18
|
next sub_parser.parse(n) if sub_parser
|
data/lib/flexparser/fragment.rb
CHANGED
@@ -31,6 +31,9 @@ module Flexparser
|
|
31
31
|
.build(doc.xpath(path, propagating_namespaces))
|
32
32
|
end
|
33
33
|
|
34
|
+
#
|
35
|
+
# The namespaces that are propagating to the child-fragment of this.
|
36
|
+
#
|
34
37
|
def propagating_namespaces
|
35
38
|
return @propagated_namespaces unless doc.respond_to?(:namespaces)
|
36
39
|
if doc.respond_to?(:collect_namespaces)
|
@@ -5,6 +5,12 @@ module Flexparser
|
|
5
5
|
#
|
6
6
|
class FragmentBuilder
|
7
7
|
class << self
|
8
|
+
#
|
9
|
+
# @param str [String|Fragment] The object that will be turned into
|
10
|
+
# a Fragment.
|
11
|
+
# @return A fragment of some kind. Either the given fragment, a new
|
12
|
+
# normal {Fragment} or en {EmptyFragment}.
|
13
|
+
#
|
8
14
|
def build(str, namespaces: {})
|
9
15
|
return str if str.is_a?(Fragment)
|
10
16
|
return EmptyFragment.new(str) if str.nil?
|
data/lib/flexparser/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flexparser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Martensen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1
|
19
|
+
version: '1'
|
20
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
|
26
|
+
version: '1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: xpath
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '2
|
33
|
+
version: '2'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '2
|
40
|
+
version: '2'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: guard
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -67,62 +67,76 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '2.4'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: bundler
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '1.13'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
82
|
+
version: '1.13'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: rake
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
89
|
+
version: '10.0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
96
|
+
version: '10.0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: minitest
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
103
|
+
version: '5'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
110
|
+
version: '5'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
112
|
+
name: rubocop
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
115
|
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: '
|
117
|
+
version: '0.52'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: '
|
125
|
-
|
124
|
+
version: '0.52'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: flay
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '2'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '2'
|
139
|
+
description: " A flexible and robust parser-dsl which is escpecially good for data-normalization.\n"
|
126
140
|
email:
|
127
141
|
- paul.martensen@gmx.de
|
128
142
|
executables: []
|
@@ -131,8 +145,8 @@ extra_rdoc_files: []
|
|
131
145
|
files:
|
132
146
|
- ".gitignore"
|
133
147
|
- ".rubocop.yml"
|
134
|
-
- ".rubocop_todo.yml"
|
135
148
|
- ".travis.yml"
|
149
|
+
- CHANGELOG.md
|
136
150
|
- Gemfile
|
137
151
|
- Guardfile
|
138
152
|
- LICENSE
|
@@ -153,7 +167,6 @@ files:
|
|
153
167
|
- lib/flexparser/tag_parser.rb
|
154
168
|
- lib/flexparser/version.rb
|
155
169
|
- lib/flexparser/xpaths.rb
|
156
|
-
- test.xml
|
157
170
|
homepage: https://github.com/lokalportal/flexparser
|
158
171
|
licenses:
|
159
172
|
- GPL-3.0
|
@@ -166,7 +179,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
166
179
|
requirements:
|
167
180
|
- - ">="
|
168
181
|
- !ruby/object:Gem::Version
|
169
|
-
version:
|
182
|
+
version: 2.1.0
|
170
183
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
171
184
|
requirements:
|
172
185
|
- - ">="
|
@@ -174,7 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
174
187
|
version: '0'
|
175
188
|
requirements: []
|
176
189
|
rubyforge_project:
|
177
|
-
rubygems_version: 2.6.
|
190
|
+
rubygems_version: 2.6.14
|
178
191
|
signing_key:
|
179
192
|
specification_version: 4
|
180
193
|
summary: A xml-parser dsl
|
data/.rubocop_todo.yml
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
# This configuration was generated by
|
2
|
-
# `rubocop --auto-gen-config`
|
3
|
-
# on 2017-08-10 12:10:56 +0200 using RuboCop version 0.49.1.
|
4
|
-
# The point is for the user to remove these configuration records
|
5
|
-
# one by one as the offenses are removed from the code base.
|
6
|
-
# Note that changes in the inspected code, or installation of new
|
7
|
-
# versions of RuboCop, may require this file to be generated again.
|
8
|
-
|
9
|
-
# Offense count: 1
|
10
|
-
Metrics/AbcSize:
|
11
|
-
Max: 16
|
12
|
-
|
13
|
-
# Offense count: 1
|
14
|
-
# Configuration parameters: CountComments, ExcludedMethods.
|
15
|
-
Metrics/BlockLength:
|
16
|
-
Max: 28
|
17
|
-
|
18
|
-
# Offense count: 6
|
19
|
-
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
20
|
-
# URISchemes: http, https
|
21
|
-
Metrics/LineLength:
|
22
|
-
Max: 105
|