xml2json 0.4.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 +7 -0
- data/.gitignore +18 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +3 -0
- data/README.md +68 -0
- data/lib/xml2json.rb +105 -0
- data/lib/xml2json/version.rb +3 -0
- data/spec/fixtures/atom.json +1 -0
- data/spec/fixtures/atom.xml +31 -0
- data/spec/fixtures/rss.json +1 -0
- data/spec/fixtures/rss.xml +36 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/xml2json_spec.rb +162 -0
- data/xml2json.gemspec +25 -0
- metadata +123 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5cc378da33fb0852ab99c25d9063fb78991beb6e
|
4
|
+
data.tar.gz: 6f4528dea35a54d0968c3fa2e69a7d2b097575bf
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1bf3da7c11920a55c1125c25b3c01315bb9337e759d4b46d81dd47e8f885edff373c875cc07ae38aa48dff57d66ba08add8cbc84388fa87b639a8c4aa7240b43
|
7
|
+
data.tar.gz: 2b730649df904d51d91444f2f2c76469a9683939b58093a00aec4dc4f9706f5d20d73e77bb640432026a8ee8378457630295120959d212cbee71faecea5ecd8e
|
data/.gitignore
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
xml2json
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.1.0
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# xml2json
|
2
|
+
|
3
|
+
[](https://codeclimate.com/github/monksoftware/xml2json)
|
4
|
+
|
5
|
+
Transforms XML into JSON
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this to your Gemfile
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'xml2json', git: 'git@github.com:monksoftware/xml2json.git'
|
13
|
+
```
|
14
|
+
|
15
|
+
## Configuration
|
16
|
+
|
17
|
+
Attributes, text and namespaces key name can be customized, defaults are `_attributes`, `_text` and `_namespaces`
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
XML2JSON.config do |c|
|
21
|
+
c.attributes_key = "attr"
|
22
|
+
c.namespaces_key = "nsp"
|
23
|
+
c.text_key = "txt"
|
24
|
+
end
|
25
|
+
```
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
XML2JSON.parse(xml_string) # => this outputs a json string
|
31
|
+
XML2JSON.parse_to_hash(xml_string) # => this outputs a ruby hash
|
32
|
+
```
|
33
|
+
|
34
|
+
## Examples
|
35
|
+
|
36
|
+
### Input XML
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
xml = '<?xml version="1.0" encoding="utf-8"?>
|
40
|
+
<root>
|
41
|
+
<author><name>Andrea</name><email>andrea@wearemonk.com</email></author>
|
42
|
+
<author><name>Giuseppe</name><email>giuseppe@wearemonk.com</email></author>
|
43
|
+
</root>'
|
44
|
+
```
|
45
|
+
|
46
|
+
### Parse to JSON string
|
47
|
+
|
48
|
+
```
|
49
|
+
XML2JSON.parse(xml)
|
50
|
+
```
|
51
|
+
|
52
|
+
output is a string
|
53
|
+
|
54
|
+
```json
|
55
|
+
{"root":{"authors":[{"name":"Andrea", "email":"andrea@wearemonk.com"},{"name":"Giuseppe", "email":"giuseppe@wearemonk.com"}]}}
|
56
|
+
```
|
57
|
+
|
58
|
+
### Parse to Ruby Hash
|
59
|
+
|
60
|
+
```
|
61
|
+
XML2JSON.parse_to_hash(xml)
|
62
|
+
```
|
63
|
+
|
64
|
+
output is a hash
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
{"root" => {"authors" => [{"name" => "Andrea", "email" => "andrea@wearemonk.com"},{"name" => "Giuseppe", "email" => "giuseppe@wearemonk.com"}]}}
|
68
|
+
```
|
data/lib/xml2json.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'json'
|
3
|
+
require 'active_support/inflector'
|
4
|
+
|
5
|
+
module XML2JSON
|
6
|
+
class InvalidXML < StandardError; end
|
7
|
+
|
8
|
+
def self.parse xml
|
9
|
+
parse_to_hash(xml).to_json
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.parse_to_hash xml
|
13
|
+
begin
|
14
|
+
doc = Nokogiri.XML(xml) { |config| config.strict }
|
15
|
+
rescue Nokogiri::XML::SyntaxError
|
16
|
+
raise InvalidXML.new
|
17
|
+
end
|
18
|
+
|
19
|
+
root = doc.root
|
20
|
+
hash = { root.name => parse_node(root) }
|
21
|
+
hash[root.name] = { self.configuration.namespaces_key => root.namespaces }.merge(hash[root.name]) unless root.namespaces.empty?
|
22
|
+
hash
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
def self.parse_node(node)
|
27
|
+
if node.element_children.count > 0
|
28
|
+
parse_attributes(node).merge(node2json(node))
|
29
|
+
else
|
30
|
+
(node.attributes.empty? ? node.text : parse_attributes(node).merge(text_hash(node)))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.text_hash(node)
|
35
|
+
return {} if node.text.strip.empty?
|
36
|
+
{ self.configuration.text_key => node.text }
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.parse_attributes(node)
|
40
|
+
node.attributes.empty? ? {} : { self.configuration.attributes_key => Hash[node.attributes.map { |k, v| [k, v.value] } ]}
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.node2json node
|
44
|
+
node.element_children.each_with_object({}) do |child, hash|
|
45
|
+
key = namespaced_node_name child
|
46
|
+
pluralized_key = key.pluralize
|
47
|
+
|
48
|
+
if hash.has_key?(key)
|
49
|
+
node_to_nodes!(hash, child)
|
50
|
+
hash.delete(key)
|
51
|
+
hash[pluralized_key] << parse_node(child)
|
52
|
+
else
|
53
|
+
if hash.has_key?(pluralized_key)
|
54
|
+
hash[pluralized_key] << parse_node(child)
|
55
|
+
else
|
56
|
+
hash[key] = parse_node(child)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.node_to_nodes! hash, node
|
64
|
+
key = namespaced_node_name(node)
|
65
|
+
if !hash[key].is_a?(Array)
|
66
|
+
tmp = hash[key]
|
67
|
+
hash[key.pluralize] = []
|
68
|
+
hash[key.pluralize] << tmp
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.namespaced_node_name node
|
73
|
+
"#{prefix(node)}#{node.name}"
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.prefix node
|
77
|
+
if !node.namespace.nil? && !node.namespace.prefix.nil? && !node.namespace.prefix.strip.empty?
|
78
|
+
"#{node.namespace.prefix}:"
|
79
|
+
else
|
80
|
+
""
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class Configuration
|
85
|
+
attr_accessor :attributes_key, :namespaces_key, :text_key
|
86
|
+
|
87
|
+
def initialize
|
88
|
+
self.attributes_key = '_attributes'
|
89
|
+
self.namespaces_key = '_namespaces'
|
90
|
+
self.text_key = '_text'
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.configuration
|
95
|
+
@configuration ||= Configuration.new
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.config
|
99
|
+
yield configuration if block_given?
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.reset
|
103
|
+
@configuration = Configuration.new
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
{"feed":{"_namespaces":{"xmlns":"http://www.w3.org/2005/Atom"},"title":"Giuseppe Modarelli","links":[{"_attributes":{"href":"http://gmodarelli.github.io/atom.xml","rel":"self"}},{"_attributes":{"href":"http://gmodarelli.github.io/"}}],"updated":"2013-12-06T08:20:23-08:00","id":"http://gmodarelli.github.io","author":{"name":"Giuseppe Modarelli"},"entries":[{"title":"Testing API with RSpec","link":{"_attributes":{"href":"http://gmodarelli.github.io/posts/2013/12/06/testing-api-with-rspec.html"}},"updated":"2013-12-06T00:00:00-08:00","id":"http://gmodarelli.github.io/posts/2013/12/06/testing-api-with-rspec","content":{"_attributes":{"type":"html"},"_text":"Text"}},{"title":"yield_successive_args with lots of args","link":{"_attributes":{"href":"http://gmodarelli.github.io/posts/2013/09/18/yield-successive-args-with-lots-of-args.html"}},"updated":"2013-09-18T00:00:00-07:00","id":"http://gmodarelli.github.io/posts/2013/09/18/yield-successive-args-with-lots-of-args","content":{"_attributes":{"type":"html"},"_text":"Text"}}]}}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<feed xmlns="http://www.w3.org/2005/Atom">
|
3
|
+
|
4
|
+
<title>Giuseppe Modarelli</title>
|
5
|
+
<link href="http://gmodarelli.github.io/atom.xml" rel="self"/>
|
6
|
+
<link href="http://gmodarelli.github.io/"/>
|
7
|
+
<updated>2013-12-06T08:20:23-08:00</updated>
|
8
|
+
<id>http://gmodarelli.github.io</id>
|
9
|
+
<author>
|
10
|
+
<name>Giuseppe Modarelli</name>
|
11
|
+
</author>
|
12
|
+
|
13
|
+
|
14
|
+
<entry>
|
15
|
+
<title>Testing API with RSpec</title>
|
16
|
+
<link href="http://gmodarelli.github.io/posts/2013/12/06/testing-api-with-rspec.html"/>
|
17
|
+
<updated>2013-12-06T00:00:00-08:00</updated>
|
18
|
+
<id>http://gmodarelli.github.io/posts/2013/12/06/testing-api-with-rspec</id>
|
19
|
+
<content type="html">Text</content>
|
20
|
+
</entry>
|
21
|
+
|
22
|
+
<entry>
|
23
|
+
<title>yield_successive_args with lots of args</title>
|
24
|
+
<link href="http://gmodarelli.github.io/posts/2013/09/18/yield-successive-args-with-lots-of-args.html"/>
|
25
|
+
<updated>2013-09-18T00:00:00-07:00</updated>
|
26
|
+
<id>http://gmodarelli.github.io/posts/2013/09/18/yield-successive-args-with-lots-of-args</id>
|
27
|
+
<content type="html">Text</content>
|
28
|
+
</entry>
|
29
|
+
|
30
|
+
|
31
|
+
</feed>
|
@@ -0,0 +1 @@
|
|
1
|
+
{"rss":{"_namespaces":{"xmlns:content":"http://purl.org/rss/1.0/modules/content/","xmlns:wfw":"http://wellformedweb.org/CommentAPI/","xmlns:dc":"http://purl.org/dc/elements/1.1/","xmlns:atom":"http://www.w3.org/2005/Atom","xmlns:sy":"http://purl.org/rss/1.0/modules/syndication/","xmlns:slash":"http://purl.org/rss/1.0/modules/slash/"},"_attributes":{"version":"2.0"},"channel":{"title":"Andrea D'Ippolito » Blog","atom:link":{"_attributes":{"href":"http://www.andreadippolito.it/blog/feed/","rel":"self","type":"application/rss+xml"}},"link":"http://www.andreadippolito.it","description":"Web Developer","lastBuildDate":"Tue, 17 Dec 2013 14:34:09 +0000","language":"en","sy:updatePeriod":"hourly","sy:updateFrequency":"1","generator":"http://wordpress.org/?v=3.3.1","item":{"title":"C’è molto da festeggiare…","link":"http://www.andreadippolito.it/eventi/ce-molto-da-festeggiare/","comments":"http://www.andreadippolito.it/eventi/ce-molto-da-festeggiare/#comments","pubDate":"Mon, 22 Feb 2010 08:00:22 +0000","dc:creator":"adedip","categories":["Eventi","setteperuno"],"guid":{"_attributes":{"isPermaLink":"false"},"_text":"http://www.andreadippolito.it/blog/?p=837"},"description":"Nel frattempo mi sono laureato… (e questo spiega la latitanza) nel futuro c’è una festa da organizzare e un progetto da portare avanti (questo spiegherà la latitanza futura). Ci vediamo","wfw:commentRss":"http://www.andreadippolito.it/eventi/ce-molto-da-festeggiare/feed/","slash:comments":"2"}}}}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<rss version="2.0"
|
3
|
+
xmlns:content="http://purl.org/rss/1.0/modules/content/"
|
4
|
+
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
|
5
|
+
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
6
|
+
xmlns:atom="http://www.w3.org/2005/Atom"
|
7
|
+
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
|
8
|
+
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
|
9
|
+
>
|
10
|
+
|
11
|
+
<channel>
|
12
|
+
<title>Andrea D'Ippolito » Blog</title>
|
13
|
+
<atom:link href="http://www.andreadippolito.it/blog/feed/" rel="self" type="application/rss+xml" />
|
14
|
+
<link>http://www.andreadippolito.it</link>
|
15
|
+
<description>Web Developer</description>
|
16
|
+
<lastBuildDate>Tue, 17 Dec 2013 14:34:09 +0000</lastBuildDate>
|
17
|
+
<language>en</language>
|
18
|
+
<sy:updatePeriod>hourly</sy:updatePeriod>
|
19
|
+
<sy:updateFrequency>1</sy:updateFrequency>
|
20
|
+
<generator>http://wordpress.org/?v=3.3.1</generator>
|
21
|
+
<item>
|
22
|
+
<title>C’è molto da festeggiare…</title>
|
23
|
+
<link>http://www.andreadippolito.it/eventi/ce-molto-da-festeggiare/</link>
|
24
|
+
<comments>http://www.andreadippolito.it/eventi/ce-molto-da-festeggiare/#comments</comments>
|
25
|
+
<pubDate>Mon, 22 Feb 2010 08:00:22 +0000</pubDate>
|
26
|
+
<dc:creator>adedip</dc:creator>
|
27
|
+
<category><![CDATA[Eventi]]></category>
|
28
|
+
<category><![CDATA[setteperuno]]></category>
|
29
|
+
|
30
|
+
<guid isPermaLink="false">http://www.andreadippolito.it/blog/?p=837</guid>
|
31
|
+
<description><![CDATA[Nel frattempo mi sono laureato… (e questo spiega la latitanza) nel futuro c’è una festa da organizzare e un progetto da portare avanti (questo spiegherà la latitanza futura). Ci vediamo]]></description>
|
32
|
+
<wfw:commentRss>http://www.andreadippolito.it/eventi/ce-molto-da-festeggiare/feed/</wfw:commentRss>
|
33
|
+
<slash:comments>2</slash:comments>
|
34
|
+
</item>
|
35
|
+
</channel>
|
36
|
+
</rss>
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'rspec/autorun'
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'xml2json'
|
4
|
+
|
5
|
+
describe XML2JSON do
|
6
|
+
describe ".parse" do
|
7
|
+
it 'jsonifies parsed hash' do
|
8
|
+
expect(XML2JSON).to receive(:parse_to_hash).with('xml').and_return({"key" => "value"})
|
9
|
+
expect(XML2JSON.parse('xml')).to eq('{"key":"value"}')
|
10
|
+
end
|
11
|
+
|
12
|
+
context "rss" do
|
13
|
+
let(:rss) { SpecHelpers.open_fixture_file('rss.xml') }
|
14
|
+
let(:json) { SpecHelpers.open_fixture_file('rss.json').delete("\n") }
|
15
|
+
|
16
|
+
it "parses the rss into json" do
|
17
|
+
hash = XML2JSON.parse(rss)
|
18
|
+
expect(hash).to eq(json)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "atom" do
|
23
|
+
let(:atom) { SpecHelpers.open_fixture_file('atom.xml') }
|
24
|
+
let(:json) { SpecHelpers.open_fixture_file('atom.json').delete("\n") }
|
25
|
+
|
26
|
+
it "parses the atom into json" do
|
27
|
+
expect(XML2JSON.parse(atom)).to eq(json)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe ".parse_to_hash" do
|
33
|
+
it "parses xml into hash" do
|
34
|
+
xml = '<a><b><c>Hello</c><d>World</d></b></a>'
|
35
|
+
json = { "a" => { "b" => { "c" => "Hello", "d" => "World" } } }
|
36
|
+
expect(XML2JSON.parse_to_hash(xml)).to eq(json)
|
37
|
+
|
38
|
+
xml = '<a><b><x>Io</x><c><d>Hello</d><e>World</e></c></b></a>'
|
39
|
+
json = { "a" => { "b" => { "x" => "Io", "c" => { "d" => "Hello", "e" => "World" } } } }
|
40
|
+
expect(XML2JSON.parse_to_hash(xml)).to eq(json)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "handles multiple elements" do
|
44
|
+
xml = '<a><x><b>Primo</b><b>Secondo</b></x></a>'
|
45
|
+
expect(XML2JSON.parse_to_hash(xml)).to(
|
46
|
+
eq({ "a" => { "x" => { "bs" => [ "Primo", "Secondo" ] } } })
|
47
|
+
)
|
48
|
+
|
49
|
+
xml = '<a><b><x>Primo</x></b><b><x>Secondo</x></b></a>'
|
50
|
+
expect(XML2JSON.parse_to_hash(xml)).to(
|
51
|
+
eq({ "a" => { "bs" => [ { "x" => "Primo" }, { "x" => "Secondo" } ] } })
|
52
|
+
)
|
53
|
+
|
54
|
+
xml = '<a><b><x>Primo</x></b><b><x>Secondo</x></b><b><x>Terzo</x></b></a>'
|
55
|
+
expect(XML2JSON.parse_to_hash(xml)).to(
|
56
|
+
eq({ "a" => { "bs" => [ { "x" => "Primo" }, { "x" => "Secondo" }, { "x" => "Terzo" }] } })
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "parses node attributes" do
|
61
|
+
xml = '<r><a url="www.google.it"></a></r>'
|
62
|
+
expect(XML2JSON.parse_to_hash(xml)).to(
|
63
|
+
eq({"r" => {"a" => { "_attributes" => {"url" => "www.google.it"}}}})
|
64
|
+
)
|
65
|
+
|
66
|
+
xml = '<r><a url="www.google.it"><b>ciao</b></a></r>'
|
67
|
+
expect(XML2JSON.parse_to_hash(xml)).to(
|
68
|
+
eq({"r" => {"a" => { "_attributes" => {"url" => "www.google.it"}, "b" => "ciao"}}})
|
69
|
+
)
|
70
|
+
|
71
|
+
xml = '<r><a url="www.google.it"></a><a url="www.google.com"></a></r>'
|
72
|
+
expect(XML2JSON.parse_to_hash(xml)).to(
|
73
|
+
eq({"r" => {"as" => [{ "_attributes" => {"url" => "www.google.it"}},{ "_attributes" => {"url" => "www.google.com"}}]}})
|
74
|
+
)
|
75
|
+
|
76
|
+
xml = '<r><a url="www.google.it"><b>ciao</b></a><a url="www.google.com"><b>ciao</b></a></r>'
|
77
|
+
expect(XML2JSON.parse_to_hash(xml)).to(
|
78
|
+
eq({"r" => {"as" => [{ "_attributes" => {"url" => "www.google.it"}, "b" => "ciao"},{ "_attributes" => {"url" => "www.google.com"}, "b" => "ciao"}]}})
|
79
|
+
)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "does not add the _text key when a node has no text" do
|
83
|
+
xml = '<r><a url="www.google.it" /></r>'
|
84
|
+
expect(XML2JSON.parse_to_hash(xml)).to(
|
85
|
+
eq({ "r" => { "a" => { "_attributes" => { "url" => "www.google.it" } } } })
|
86
|
+
)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "parses root attributes" do
|
90
|
+
xml = '<r id="1"><a>Hello</a></r>'
|
91
|
+
expect(XML2JSON.parse_to_hash(xml)).to(
|
92
|
+
eq({"r" => {"_attributes" => { "id" => "1" }, "a" => "Hello" } })
|
93
|
+
)
|
94
|
+
end
|
95
|
+
|
96
|
+
context "namespaces" do
|
97
|
+
let(:xml) { '<r xmlns:content="http://purl.org/rss/1.0/modules/content/"><content:encoded>Hello</content:encoded><content:encoded>World</content:encoded></r>' }
|
98
|
+
it "parses namespaced node names" do
|
99
|
+
expect(XML2JSON.parse_to_hash(xml)).to(
|
100
|
+
eq({"r" => { "_namespaces" => { "xmlns:content" => "http://purl.org/rss/1.0/modules/content/" }, "content:encodeds" => [ "Hello", "World" ] } })
|
101
|
+
)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context "invalid xml file" do
|
106
|
+
it "raises an exception if the xml file is bad formed" do
|
107
|
+
xml = '<invalid></xml>'
|
108
|
+
expect {
|
109
|
+
XML2JSON.parse_to_hash(xml)
|
110
|
+
}.to raise_error XML2JSON::InvalidXML
|
111
|
+
|
112
|
+
xml = 'not xml file'
|
113
|
+
expect {
|
114
|
+
XML2JSON.parse_to_hash(xml)
|
115
|
+
}.to raise_error XML2JSON::InvalidXML
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context "pluralize" do
|
120
|
+
it "pluralizes keys name when multiple nodes" do
|
121
|
+
xml = '<root><item>Primo</item><item>Secondo</item></root>'
|
122
|
+
expect(XML2JSON.parse_to_hash(xml)).to(
|
123
|
+
eq({ "root" => { "items" => [ "Primo", "Secondo"] } })
|
124
|
+
)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context "configuration" do
|
130
|
+
after do
|
131
|
+
XML2JSON.reset
|
132
|
+
end
|
133
|
+
|
134
|
+
it "let's the user choose the keys" do
|
135
|
+
XML2JSON.config do |c|
|
136
|
+
c.attributes_key = 'attr'
|
137
|
+
c.namespaces_key = 'names'
|
138
|
+
c.text_key = 'body'
|
139
|
+
end
|
140
|
+
expect(XML2JSON.configuration.attributes_key).to eq('attr')
|
141
|
+
expect(XML2JSON.configuration.namespaces_key).to eq('names')
|
142
|
+
expect(XML2JSON.configuration.text_key).to eq('body')
|
143
|
+
end
|
144
|
+
|
145
|
+
it "provides default values" do
|
146
|
+
expect(XML2JSON.configuration.attributes_key).to eq('_attributes')
|
147
|
+
expect(XML2JSON.configuration.namespaces_key).to eq('_namespaces')
|
148
|
+
expect(XML2JSON.configuration.text_key).to eq('_text')
|
149
|
+
end
|
150
|
+
|
151
|
+
it "restores the default values" do
|
152
|
+
XML2JSON.config do |c|
|
153
|
+
c.attributes_key = 'attr'
|
154
|
+
end
|
155
|
+
|
156
|
+
expect(XML2JSON.configuration.attributes_key).to eq('attr')
|
157
|
+
XML2JSON.reset
|
158
|
+
|
159
|
+
expect(XML2JSON.configuration.attributes_key).to eq('_attributes')
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
data/xml2json.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'xml2json/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "xml2json"
|
8
|
+
spec.version = XML2JSON::VERSION
|
9
|
+
spec.authors = ["Giuseppe Modarelli", "Andrea D'Ippolito"]
|
10
|
+
spec.email = ["giuseppe.modarelli@gmail.com","adedip@gmail.com"]
|
11
|
+
spec.summary = %q{Turn XML into JSON}
|
12
|
+
spec.description = %q{Turn XML into JSON}
|
13
|
+
spec.homepage = "https://github.com/monksoftware/xml2json"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
22
|
+
spec.add_development_dependency "rspec", "~> 2.14"
|
23
|
+
spec.add_dependency "nokogiri", "~> 1.6"
|
24
|
+
spec.add_dependency "activesupport", "~> 4.0"
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: xml2json
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Giuseppe Modarelli
|
8
|
+
- Andrea D'Ippolito
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-06-24 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.5'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.5'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rspec
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '2.14'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '2.14'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: nokogiri
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '1.6'
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '1.6'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: activesupport
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '4.0'
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '4.0'
|
70
|
+
description: Turn XML into JSON
|
71
|
+
email:
|
72
|
+
- giuseppe.modarelli@gmail.com
|
73
|
+
- adedip@gmail.com
|
74
|
+
executables: []
|
75
|
+
extensions: []
|
76
|
+
extra_rdoc_files: []
|
77
|
+
files:
|
78
|
+
- ".gitignore"
|
79
|
+
- ".ruby-gemset"
|
80
|
+
- ".ruby-version"
|
81
|
+
- Gemfile
|
82
|
+
- Gemfile.lock
|
83
|
+
- README.md
|
84
|
+
- lib/xml2json.rb
|
85
|
+
- lib/xml2json/version.rb
|
86
|
+
- spec/fixtures/atom.json
|
87
|
+
- spec/fixtures/atom.xml
|
88
|
+
- spec/fixtures/rss.json
|
89
|
+
- spec/fixtures/rss.xml
|
90
|
+
- spec/spec_helper.rb
|
91
|
+
- spec/xml2json_spec.rb
|
92
|
+
- xml2json.gemspec
|
93
|
+
homepage: https://github.com/monksoftware/xml2json
|
94
|
+
licenses:
|
95
|
+
- MIT
|
96
|
+
metadata: {}
|
97
|
+
post_install_message:
|
98
|
+
rdoc_options: []
|
99
|
+
require_paths:
|
100
|
+
- lib
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
requirements: []
|
112
|
+
rubyforge_project:
|
113
|
+
rubygems_version: 2.2.2
|
114
|
+
signing_key:
|
115
|
+
specification_version: 4
|
116
|
+
summary: Turn XML into JSON
|
117
|
+
test_files:
|
118
|
+
- spec/fixtures/atom.json
|
119
|
+
- spec/fixtures/atom.xml
|
120
|
+
- spec/fixtures/rss.json
|
121
|
+
- spec/fixtures/rss.xml
|
122
|
+
- spec/spec_helper.rb
|
123
|
+
- spec/xml2json_spec.rb
|