shax 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (8) hide show
  1. checksums.yaml +7 -0
  2. data/.ruby-version +1 -0
  3. data/Gemfile +3 -0
  4. data/LICENSE +21 -0
  5. data/README.md +50 -0
  6. data/lib/shax.rb +156 -0
  7. data/shax.gemspec +13 -0
  8. 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
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
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: []