shax 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.ruby-version +1 -0
- data/Gemfile +3 -0
- data/LICENSE +21 -0
- data/README.md +50 -0
- data/lib/shax.rb +156 -0
- data/shax.gemspec +13 -0
- metadata +49 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 99e3bbd5b80c4c8b5eca83391f379d7408efa23e3af5fd9675f7f830217447e6
|
4
|
+
data.tar.gz: 33a60b557fef3bb6b1a76cb1d4679443a5a5b644921ab167b91e096754e4cbca
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: '0285ed5028df98d528c07c6a7ef83dc060f2c6334501479aebfaf79746f2d68978ac2cdba3a6987f30bffbdb6b5f9b77cc812b3415a2695303933636340eb9e8'
|
7
|
+
data.tar.gz: c4dd157ab6a95fc462f4a310ee4269d4817e188b57e5784358643b6019a52817b0e45077d54f6e4726e2bfe37373478745090cecedcb8e0bc9cbd26d978d7848
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.5
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2019 Steve Shreeve
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# shax
|
2
|
+
|
3
|
+
`shax` is a Ruby gem that makes it easy to parse XML. Helpful for use with SOAP, etc.
|
4
|
+
|
5
|
+
## Examples
|
6
|
+
|
7
|
+
Parsing this XML snippet:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
xml = Shax.load <<~""
|
11
|
+
<x:Envelope xmlns:x="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:cf="http://schemas.datacontract.org/2004/07/CF.Gateway.FIS.Dto">
|
12
|
+
<x:Header/>
|
13
|
+
<x:Body>
|
14
|
+
<tem:TransHistDetailInquiry>
|
15
|
+
<tem:request>
|
16
|
+
<cf:CustomerNumber>ABC123</cf:CustomerNumber>
|
17
|
+
<cf:ComplementDate>343434</cf:ComplementDate>
|
18
|
+
<cf:ComplementTime>767676</cf:ComplementTime>
|
19
|
+
<cf:StakeholderID>XYZPDQ</cf:StakeholderID>
|
20
|
+
</tem:request>
|
21
|
+
<tem:cfGatewayID>ClientName</tem:cfGatewayID>
|
22
|
+
<tem:cfServiceKey>SecretKeyGoesHere</tem:cfServiceKey>
|
23
|
+
</tem:TransHistDetailInquiry>
|
24
|
+
</x:Body>
|
25
|
+
</x:Envelope>
|
26
|
+
|
27
|
+
Shax.show xml
|
28
|
+
```
|
29
|
+
|
30
|
+
Produces the following hash:
|
31
|
+
|
32
|
+
```text
|
33
|
+
{
|
34
|
+
"Envelope" => {
|
35
|
+
"Header" => "",
|
36
|
+
"Body" => {
|
37
|
+
"TransHistDetailInquiry" => {
|
38
|
+
"request" => {
|
39
|
+
"CustomerNumber" => "ABC123",
|
40
|
+
"ComplementDate" => "343434",
|
41
|
+
"ComplementTime" => "767676",
|
42
|
+
"StakeholderID" => "XYZPDQ",
|
43
|
+
},
|
44
|
+
"cfGatewayID" => "ClientName",
|
45
|
+
"cfServiceKey" => "SecretKeyGoesHere",
|
46
|
+
},
|
47
|
+
},
|
48
|
+
},
|
49
|
+
}
|
50
|
+
```
|
data/lib/shax.rb
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
class Shax
|
2
|
+
attr_accessor :xml, :root
|
3
|
+
|
4
|
+
class Node
|
5
|
+
attr_accessor :tag, :parent, :val, :kids
|
6
|
+
|
7
|
+
def initialize(tag=nil, parent=nil, val=nil)
|
8
|
+
@tag = tag
|
9
|
+
@parent = parent
|
10
|
+
@val = val
|
11
|
+
@kids = []
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
Tags = %r`
|
16
|
+
<(/?[-\w:.]+) # 1: tag (loose, but probably ok)
|
17
|
+
([^>]+)?> # 2: atts
|
18
|
+
((?:<!\[CDATA\[[\s\S]*?\]\]>|[^<]+)+)? # 3: text
|
19
|
+
`mx
|
20
|
+
|
21
|
+
Atts = %r`
|
22
|
+
([-\w:.]+)\s*=\s* # 1: name
|
23
|
+
(['"]) # 2: quote
|
24
|
+
([\s\S]*?)\2 # 3: value
|
25
|
+
`x
|
26
|
+
|
27
|
+
Data = %r`
|
28
|
+
<!\[CDATA\[([\s\S]*?)\]\]>
|
29
|
+
`x
|
30
|
+
|
31
|
+
def self.load(str)
|
32
|
+
new(str).convert
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.load!(str, deep=4)
|
36
|
+
(+load(str))[['*'] * deep * '/']
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.show(obj, lev=0)
|
40
|
+
min = ' ' * (lev + 0)
|
41
|
+
pre = ' ' * (lev + 1)
|
42
|
+
puts "{" if lev == 0
|
43
|
+
case obj
|
44
|
+
when Hash
|
45
|
+
obj.each do |k, v|
|
46
|
+
case v
|
47
|
+
when Hash
|
48
|
+
puts "#{pre}#{k.inspect} => {"
|
49
|
+
show(v, lev + 1)
|
50
|
+
puts "#{pre}},"
|
51
|
+
when Array
|
52
|
+
puts "#{pre}#{k.inspect} => ["
|
53
|
+
show(v, lev + 2)
|
54
|
+
puts "#{pre}],"
|
55
|
+
else
|
56
|
+
puts "#{pre}#{k.inspect} => #{v.inspect},"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
when Array
|
60
|
+
obj.each do |v|
|
61
|
+
case v
|
62
|
+
when Hash
|
63
|
+
puts "#{pre}{"
|
64
|
+
show(v, lev + 1)
|
65
|
+
puts "#{pre}},"
|
66
|
+
when Array
|
67
|
+
abort "ERROR: arrays of arrays not yet supported"
|
68
|
+
else
|
69
|
+
puts "#{min}#{v.inspect},"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
puts "}" if lev == 0
|
74
|
+
end
|
75
|
+
|
76
|
+
def initialize(xml)
|
77
|
+
@xml = xml
|
78
|
+
@root = parse xml
|
79
|
+
end
|
80
|
+
|
81
|
+
def parse(str)
|
82
|
+
node = root = Node.new "!xml"
|
83
|
+
tags = []; str.scan(Tags).each {|hits| tags.push(hits)}
|
84
|
+
skip = nil
|
85
|
+
|
86
|
+
tags.each_with_index do |(tag, atts, text), i|
|
87
|
+
next if i == skip
|
88
|
+
|
89
|
+
# closing tag
|
90
|
+
if tag[0] == '/'
|
91
|
+
node = node.parent
|
92
|
+
|
93
|
+
# create baby
|
94
|
+
else
|
95
|
+
node.kids.push(baby = Node.new(tag, node))
|
96
|
+
# baby.atts = @parse_atts atts if atts? # if config.atts
|
97
|
+
|
98
|
+
# self-closing tag
|
99
|
+
if atts && atts[-1] == '/'
|
100
|
+
baby.val = ''
|
101
|
+
|
102
|
+
# text node
|
103
|
+
elsif ((skip = i + 1) < tags.size) and tags[skip][0] == "/#{tag}"
|
104
|
+
# baby.val = @value text?...
|
105
|
+
# baby.val = !text ? '' : text.scan(Data).each {|hits| hits[0]}
|
106
|
+
baby.val = text
|
107
|
+
|
108
|
+
# starting tag
|
109
|
+
else
|
110
|
+
node = baby
|
111
|
+
skip = nil
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
root
|
116
|
+
end
|
117
|
+
|
118
|
+
def parse_atts(str)
|
119
|
+
if str and (str = str.strip!).length > 3
|
120
|
+
atts = {}
|
121
|
+
str.scan(Atts).each {|hits| atts["#{skip_ns(hits[1])}"] = value hits[3]}
|
122
|
+
atts
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def skip_ns(str)
|
127
|
+
return str unless str.include?(':')
|
128
|
+
pre = str[0] == '/' ? '/' : ''
|
129
|
+
pre = str.split(':', 2)[-1]
|
130
|
+
end
|
131
|
+
|
132
|
+
def value(str)
|
133
|
+
return '' unless str
|
134
|
+
return '' + str # if isNan str ???
|
135
|
+
return str.to_f if str.include? '.'
|
136
|
+
return str.to_i
|
137
|
+
end
|
138
|
+
|
139
|
+
def convert(node=@root)
|
140
|
+
return node.val if node.val
|
141
|
+
out = {}
|
142
|
+
for kid in node.kids
|
143
|
+
obj = convert kid
|
144
|
+
tag = kid.tag
|
145
|
+
tag = skip_ns tag
|
146
|
+
if out.key?(tag)
|
147
|
+
val = out[tag]
|
148
|
+
out[tag] = [val] unless val.is_a?(Array)
|
149
|
+
out[tag].push obj
|
150
|
+
else
|
151
|
+
out[tag] = obj
|
152
|
+
end
|
153
|
+
end
|
154
|
+
out
|
155
|
+
end
|
156
|
+
end
|
data/shax.gemspec
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "shax"
|
5
|
+
s.version = "0.5.0"
|
6
|
+
s.author = "Steve Shreeve"
|
7
|
+
s.email = "steve.shreeve@gmail.com"
|
8
|
+
s.summary = "Shax is a Ruby gem that makes it easy to parse XML"
|
9
|
+
s.description = "Useful for parsing XML into a standard Ruby object"
|
10
|
+
s.homepage = "https://github.com/shreeve/shax"
|
11
|
+
s.license = "MIT"
|
12
|
+
s.files = `git ls-files`.split("\n") - %w[.gitignore]
|
13
|
+
end
|
metadata
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: shax
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Steve Shreeve
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-08-23 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Useful for parsing XML into a standard Ruby object
|
14
|
+
email: steve.shreeve@gmail.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- ".ruby-version"
|
20
|
+
- Gemfile
|
21
|
+
- LICENSE
|
22
|
+
- README.md
|
23
|
+
- lib/shax.rb
|
24
|
+
- shax.gemspec
|
25
|
+
homepage: https://github.com/shreeve/shax
|
26
|
+
licenses:
|
27
|
+
- MIT
|
28
|
+
metadata: {}
|
29
|
+
post_install_message:
|
30
|
+
rdoc_options: []
|
31
|
+
require_paths:
|
32
|
+
- lib
|
33
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - ">="
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
requirements: []
|
44
|
+
rubyforge_project:
|
45
|
+
rubygems_version: 2.7.7
|
46
|
+
signing_key:
|
47
|
+
specification_version: 4
|
48
|
+
summary: Shax is a Ruby gem that makes it easy to parse XML
|
49
|
+
test_files: []
|