awesome_xml 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +78 -2
- data/lib/awesome_xml.rb +1 -0
- data/lib/awesome_xml/class_methods.rb +4 -0
- data/lib/awesome_xml/native_type.rb +14 -2
- data/lib/awesome_xml/node_evaluator.rb +7 -2
- data/lib/awesome_xml/node_xpath.rb +13 -14
- data/lib/awesome_xml/type.rb +2 -1
- data/lib/awesome_xml/types/void.rb +22 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '09184adda9b06ea9f6219d70c4a73639e1f24a82'
|
4
|
+
data.tar.gz: e6fa8cb7358a7e0eef58e3c5ba312e104c5df4a4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0334bed7e8863a5ce46ccc245e72266f66e561f200d610a7d79868454f5761a7742055ebe6fc8f4d147d194742eca7c144155f4117e9a53dd169be8cb3669b59
|
7
|
+
data.tar.gz: 68870e318cbba35b3046d5a9acd411e9d77c300e611340b4616343f79c0dc04043352749973282133a0beffc921c13c91be19d35596fadbfd92d988512e191c4
|
data/README.md
CHANGED
@@ -42,7 +42,7 @@ Its arguments are
|
|
42
42
|
- an options hash (optional)
|
43
43
|
|
44
44
|
The type can either be a native type given in the form of a symbol (currently supported are `:text`,
|
45
|
-
`:integer`, `:float`, `:duration` and `:
|
45
|
+
`:integer`, `:float`, `:duration`, `:date_time` and `:void`), or a custom class. You can also pass in a string containing
|
46
46
|
a class name in case the class constant is not yet defined at the time you run the `.node` method.
|
47
47
|
More about that later.
|
48
48
|
|
@@ -271,6 +271,48 @@ class MyDocument
|
|
271
271
|
end
|
272
272
|
```
|
273
273
|
|
274
|
+
## Node names
|
275
|
+
|
276
|
+
There are three options you can use in case you want to parse not the content of an element or attribute,
|
277
|
+
but the name of it: `:element_name`, `:attribute_name`, `:self_name`. Those will parse the name of the element or
|
278
|
+
the attribute specified by the name of the node or by an `:xpath` option, or the name of the current node itself.
|
279
|
+
|
280
|
+
Let's look at an example:
|
281
|
+
|
282
|
+
```xml
|
283
|
+
<document>
|
284
|
+
<heap1>
|
285
|
+
<item ref='a'/>
|
286
|
+
</heap1>
|
287
|
+
<heap2>
|
288
|
+
<item ref='b'/>
|
289
|
+
</heap2>
|
290
|
+
</document>
|
291
|
+
```
|
292
|
+
|
293
|
+
Now let's assume you want your hash to equal
|
294
|
+
```ruby
|
295
|
+
{ items: [ { ref: 'a', heap: 'heap1' }, { ref: 'b', heap: 'heap2' } ] }
|
296
|
+
```
|
297
|
+
|
298
|
+
You can solve this by using `element_name: true`:
|
299
|
+
|
300
|
+
```ruby
|
301
|
+
class MyDocument
|
302
|
+
include AwesomeXML
|
303
|
+
|
304
|
+
set_context 'document'
|
305
|
+
node :items, 'Item', array: true, xpath: '//item'
|
306
|
+
|
307
|
+
class Item
|
308
|
+
include AwesomeXML
|
309
|
+
|
310
|
+
node :ref, :text, attribute: true
|
311
|
+
node :heap, :text, element_name: true, xpath: '../'
|
312
|
+
end
|
313
|
+
end
|
314
|
+
```
|
315
|
+
|
274
316
|
Awesome, right? You've got a few more notches you can kick it up, though.
|
275
317
|
|
276
318
|
## Passing blocks
|
@@ -477,7 +519,9 @@ or doesn't even exist. For the former, use `:default_empty`, for the latter, use
|
|
477
519
|
|
478
520
|
## More node types
|
479
521
|
|
480
|
-
|
522
|
+
### Duration nodes
|
523
|
+
|
524
|
+
As you may remember, `:duration` is of the native types for `.node`.
|
481
525
|
They return `ActiveSupport::Duration` objects, which interact freely with each other and with `Time` and
|
482
526
|
`DateTime` objects.
|
483
527
|
The special thing about them is that they take a *mandatory* `:format` option. There, you can specify the
|
@@ -496,3 +540,35 @@ but when the numbers are single digit, it looks like `'2m1'`. In this case, just
|
|
496
540
|
`parse_length`. Everything up to the following character (or the end of the duration string) will be
|
497
541
|
treated as going into the parsed value. The format string that would parse you the correct duration
|
498
542
|
would be `'{M}m{S}'`.
|
543
|
+
|
544
|
+
### Void nodes
|
545
|
+
|
546
|
+
This type is used if you don't actually want to parse anything. For example, if you simply want to count the
|
547
|
+
occurrence of a tag. The result of the parsing operation is simply the node(s) itself. Suppose your XML document
|
548
|
+
is this:
|
549
|
+
|
550
|
+
```xml
|
551
|
+
<document>
|
552
|
+
<items>
|
553
|
+
<item>1234</item>
|
554
|
+
<item>4321</item>
|
555
|
+
<item>5678</item>
|
556
|
+
</items>
|
557
|
+
</document>
|
558
|
+
```
|
559
|
+
|
560
|
+
And you want your ruby hash to be
|
561
|
+
```ruby
|
562
|
+
{ number_of_items: 3 }
|
563
|
+
```
|
564
|
+
|
565
|
+
This will do it for you:
|
566
|
+
|
567
|
+
```ruby
|
568
|
+
class MyDocument
|
569
|
+
include AwesomeXML
|
570
|
+
|
571
|
+
set_context 'document/items'
|
572
|
+
node(:number_of_items, :void, element: 'item', array: true) { |nodes| nodes.size }
|
573
|
+
end
|
574
|
+
```
|
data/lib/awesome_xml.rb
CHANGED
@@ -4,12 +4,18 @@
|
|
4
4
|
# interface for types that the `AwesomeXML::NodeEvaluator` expects.
|
5
5
|
module AwesomeXML
|
6
6
|
module NativeType
|
7
|
+
def self.included(base)
|
8
|
+
base.class_eval do
|
9
|
+
base.extend(AwesomeXML::NativeType::ClassMethods)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
7
13
|
attr_reader :string, :options
|
8
14
|
private :string, :options
|
9
15
|
|
10
16
|
# Native type instances are initialized with a `Nokogiri::XML` object and an options hash.
|
11
|
-
def initialize(
|
12
|
-
@string =
|
17
|
+
def initialize(string, options)
|
18
|
+
@string = string
|
13
19
|
@options = options
|
14
20
|
end
|
15
21
|
|
@@ -19,6 +25,12 @@ module AwesomeXML
|
|
19
25
|
@value ||= with_defaults { parse_value }
|
20
26
|
end
|
21
27
|
|
28
|
+
module ClassMethods
|
29
|
+
def parsing_type?
|
30
|
+
true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
22
34
|
private
|
23
35
|
|
24
36
|
def with_defaults(&block)
|
@@ -21,14 +21,19 @@ module AwesomeXML
|
|
21
21
|
# type passed in in the form of a class that handles the conversion.
|
22
22
|
def call
|
23
23
|
if options[:array]
|
24
|
-
all_nodes.map { |node| type_class.new(node, options).evaluate }
|
24
|
+
all_nodes.map { |node| type_class.new(content(node), options).evaluate }
|
25
25
|
else
|
26
|
-
type_class.new(first_node, options).evaluate
|
26
|
+
type_class.new(content(first_node), options).evaluate
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
30
|
private
|
31
31
|
|
32
|
+
def content(node)
|
33
|
+
return node unless type_class.parsing_type?
|
34
|
+
(options[:element_name] || options[:attribute_name] || options[:self_name]) ? node&.name : node&.text
|
35
|
+
end
|
36
|
+
|
32
37
|
def all_nodes
|
33
38
|
xml_in_context&.xpath(xpath)
|
34
39
|
end
|
@@ -3,40 +3,39 @@
|
|
3
3
|
# This class's responsibility is to build an XPath from specified options.
|
4
4
|
module AwesomeXML
|
5
5
|
class NodeXPath
|
6
|
-
attr_reader :node_name, :
|
7
|
-
private :node_name, :
|
6
|
+
attr_reader :node_name, :options
|
7
|
+
private :node_name, :options
|
8
8
|
|
9
9
|
# Initialize this class by providing the name of the `AwesomeXML` node and an options hash.
|
10
10
|
# For more information on how the options work, please refer to the README.
|
11
11
|
def initialize(node_name, options)
|
12
12
|
@node_name = node_name
|
13
|
-
@
|
14
|
-
@element_option = options[:element]
|
15
|
-
@attribute_option = options[:attribute]
|
16
|
-
@self_option = options[:self]
|
17
|
-
@look_for = options[:look_for]
|
18
|
-
@array = options[:array]
|
13
|
+
@options = options
|
19
14
|
end
|
20
15
|
|
21
16
|
# Returns a String representing an XPath built from the options passed in at initialization time.
|
22
17
|
def xpath
|
23
|
-
|
18
|
+
options[:xpath] || xpath_by_tag_type
|
24
19
|
end
|
25
20
|
|
26
21
|
private
|
27
22
|
|
28
23
|
def xpath_by_tag_type
|
29
|
-
if
|
30
|
-
"./@#{tag_name(
|
31
|
-
elsif
|
24
|
+
if options[:attribute]
|
25
|
+
"./@#{tag_name(options[:attribute])}"
|
26
|
+
elsif options[:attribute_name]
|
27
|
+
"./@#{tag_name(true)}"
|
28
|
+
elsif options[:self] || options[:self_name]
|
32
29
|
"."
|
30
|
+
elsif options[:element_name]
|
31
|
+
"./#{tag_name(true)}"
|
33
32
|
else
|
34
|
-
"./#{tag_name(
|
33
|
+
"./#{tag_name(options[:element])}"
|
35
34
|
end
|
36
35
|
end
|
37
36
|
|
38
37
|
def node_name_singular
|
39
|
-
array ? node_name.to_s.singularize.to_sym : node_name
|
38
|
+
options[:array] ? node_name.to_s.singularize.to_sym : node_name
|
40
39
|
end
|
41
40
|
|
42
41
|
def tag_name(option)
|
data/lib/awesome_xml/type.rb
CHANGED
@@ -9,7 +9,8 @@ module AwesomeXML
|
|
9
9
|
integer: AwesomeXML::Integer,
|
10
10
|
float: AwesomeXML::Float,
|
11
11
|
duration: AwesomeXML::Duration,
|
12
|
-
date_time: AwesomeXML::DateTime
|
12
|
+
date_time: AwesomeXML::DateTime,
|
13
|
+
void: AwesomeXML::Void
|
13
14
|
}.freeze
|
14
15
|
|
15
16
|
# Takes a type (Symbol, String or Class) passed in from a `.node` method call and the
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# A class that knows how to not parse but simply pass on a node.
|
4
|
+
module AwesomeXML
|
5
|
+
class Void
|
6
|
+
attr_reader :node
|
7
|
+
private :node
|
8
|
+
|
9
|
+
def initialize(node, options)
|
10
|
+
@node = node
|
11
|
+
@options = options
|
12
|
+
end
|
13
|
+
|
14
|
+
def evaluate
|
15
|
+
node
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.parsing_type?
|
19
|
+
false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: awesome_xml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Felix Lublasser
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-06-
|
11
|
+
date: 2017-06-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -121,6 +121,7 @@ files:
|
|
121
121
|
- lib/awesome_xml/types/float.rb
|
122
122
|
- lib/awesome_xml/types/integer.rb
|
123
123
|
- lib/awesome_xml/types/text.rb
|
124
|
+
- lib/awesome_xml/types/void.rb
|
124
125
|
homepage: https://github.com/fromAtoB/awesome_xml
|
125
126
|
licenses:
|
126
127
|
- MIT
|