simple-xml 1.0.0

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.
@@ -0,0 +1,22 @@
1
+ # SimpleXML
2
+
3
+ A simple add on to rexml to parse xml data simply by converting them to a hash.
4
+ That hash can than easily be passed to model objects to validate etc.
5
+
6
+ Example usage:
7
+
8
+ ```ruby
9
+ doc = REXML::Document.new(%Q{
10
+ <?xml version="1.0"?>
11
+ <address>
12
+ <country iso_code="de" nationality="deutsch">Deutschland</country>
13
+ <zip_code>76135</zip_code>
14
+ <city>Karlsruhe</city>
15
+ <street>
16
+ <name_and_number>Ernst-Frey-Str. 10</name_and_number>
17
+ </street>
18
+ </address>
19
+ }
20
+ doc.simplify("/address") #=> { :country => "Deutschland", :zip_code => "76135", :city => "Karlsruhe", :street => { :name_and_number => "Ernst-Frey-Str. 10" } }
21
+ doc.simplify_attributes("/address/country") #=> { :iso_code => "de", :nationality => "deutsch" }
22
+ ```
@@ -0,0 +1,5 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ RSpec::Core::RakeTask.new(:spec)
4
+
5
+ task :default => :spec
@@ -0,0 +1,7 @@
1
+ require "rexml/document"
2
+ require "rexml/xpath"
3
+ require File.join(File.dirname(__FILE__), "simple_xml", "simplifyer")
4
+
5
+ class REXML::Element
6
+ include SimpleXML::Simplifyer
7
+ end
@@ -0,0 +1,90 @@
1
+ module SimpleXML
2
+ # Extension to the element class of rexml to make working with simple xml
3
+ # documents more easy and intuitive. Therefor it uses the combination of hashes
4
+ # and the rexml XPath implementation.
5
+ # @example Usage with a simple document
6
+ # doc = REXML::Document.new(%Q{
7
+ # <?xml version="1.0"?>
8
+ # <address>
9
+ # <country iso_code="de" nationality="deutsch">Deutschland</country>
10
+ # <zip_code>76135</zip_code>
11
+ # <city>Karlsruhe</city>
12
+ # <street>
13
+ # <name_and_number>Ernst-Frey-Str. 10</name_and_number>
14
+ # </street>
15
+ # </address>
16
+ # }
17
+ # doc.simplify("/address") #=> { :country => "Deutschland", :zip_code => "76135", :city => "Karlsruhe", :street => { :name_and_number => "Ernst-Frey-Str. 10" } }
18
+ # doc.simplify_attributes("/address/country") #=> { :iso_code => "de", :nationality => "deutsch" }
19
+ #
20
+ module Simplifyer
21
+ # Simplifies the current element or an xpath to a subelement to a hash.
22
+ # @param [String] xpath an optional xpath for an element to convert
23
+ # @return [Hash, NilClass] nil if the xpath didn't match to a node or a hash otherwise.
24
+ # If elements have the same name they will be merged into an array.
25
+ def simplify(xpath = nil)
26
+ if xpath
27
+ if element = REXML::XPath.first(self, xpath)
28
+ element.simplify
29
+ else
30
+ nil
31
+ end
32
+ else
33
+ # just convert the elements if there are some
34
+ if contains_no_text_elements?
35
+ tree = {} # the subtree
36
+ last_name = nil # helper for detecting duplicate element names
37
+ self.each do |element|
38
+ # we ignore all text elements that are in between the elements
39
+ if element.is_a? REXML::Element
40
+ name = element.name.to_sym
41
+ if last_name == name
42
+ # create an array if there is more than one element with
43
+ # the same name
44
+ tree[name] = [tree[name]] unless tree[name].is_a?(Array)
45
+ tree[name] += [element.simplify]
46
+ else
47
+ # create a simple element (key - value) in the hash
48
+ tree[name] = element.simplify
49
+ last_name = name
50
+ end
51
+ end
52
+ end
53
+ tree
54
+ else
55
+ # if there is just text left the text elements will be used
56
+ self.text
57
+ end
58
+ end
59
+ end
60
+
61
+ # Simplifies the current element attributes or an xpath to subelement
62
+ # attributes to a hash.
63
+ # @param [String] xpath an optional xpath for an element to convert
64
+ # @return [Hash, NilClass] nil if the xpath didn't match to a node or a hash otherwise.
65
+ def simplify_attributes(xpath = nil)
66
+ if xpath
67
+ if element = REXML::XPath.first(self, xpath)
68
+ element.simplify_attributes
69
+ else
70
+ nil
71
+ end
72
+ else
73
+ hash = {}
74
+ attributes.each { |key, value| hash[key.to_sym] = value }
75
+ hash
76
+ end
77
+ end
78
+
79
+ private
80
+
81
+ # Checks if the sub element has any other elements than text elements.
82
+ # @returns [Boolean] ture if there is at least one REXML::Element
83
+ def contains_no_text_elements?
84
+ children.each do |element|
85
+ return true if element.is_a? REXML::Element
86
+ end
87
+ false
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,3 @@
1
+ module SimpleXML
2
+ VERSION = '1.0.0'
3
+ end
@@ -0,0 +1,37 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push('lib')
3
+ require "simple_xml/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "simple-xml"
7
+ s.version = SimpleXML::VERSION.dup
8
+ s.date = "2011-11-21"
9
+ s.summary = "Some helpers for REXML::Element to create hashes from xml easily"
10
+ s.email = "vilandgr+simplexml@googlemail.com"
11
+ s.homepage = "https://github.com/threez/simple-xml"
12
+ s.authors = ['Vincent Landgraf']
13
+
14
+ s.description = "Some helpers for REXML::Element to create hashes from xml easily."
15
+
16
+ dependencies = [
17
+ [:development, "rspec", "~> 2.1"],
18
+ ]
19
+
20
+ s.files = Dir['**/*']
21
+ s.test_files = Dir['test/**/*'] + Dir['spec/**/*']
22
+ s.executables = Dir['bin/*'].map { |f| File.basename(f) }
23
+ s.require_paths = ["lib"]
24
+
25
+ ## Make sure you can build the gem on older versions of RubyGems too:
26
+ s.rubygems_version = "1.8.10"
27
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
28
+ s.specification_version = 3 if s.respond_to? :specification_version
29
+
30
+ dependencies.each do |type, name, version|
31
+ if s.respond_to?("add_#{type}_dependency")
32
+ s.send("add_#{type}_dependency", name, version)
33
+ else
34
+ s.add_dependency(name, version)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,91 @@
1
+ require 'spec_helper'
2
+
3
+ describe REXML::Element do
4
+ before(:each) do
5
+ @doc = REXML::Document.new(%Q{
6
+ <?xml version="1.0"?>
7
+ <user>
8
+ <address>
9
+ <country iso_code="de" nationality="deutsch">Deutschland</country>
10
+ <zip_code>76135</zip_code>
11
+ <city>Karlsruhe</city>
12
+ <street>
13
+ <name_and_number>Ernst-Frey-Str. 10</name_and_number>
14
+ </street>
15
+ </address>
16
+ <phones>
17
+ <phone type="MOBILE">
18
+ <country>+49</country>
19
+ <provider>171</provider>
20
+ <number>20333232</number>
21
+ </phone>
22
+ <phone type="HOME">+494534520085285</phone>
23
+ <phone type="WORK">+494534523453453</phone>
24
+ </phones>
25
+ </user>
26
+ })
27
+ end
28
+
29
+ it "should be possible not fail if the node doesn't exists" do
30
+ @doc.simplify("/user/no-element").should == nil
31
+ end
32
+
33
+ it "should be possible to call on root element without a xpath" do
34
+ @doc.simplify.should == {
35
+ :user => {
36
+ :address => {
37
+ :country => "Deutschland",
38
+ :zip_code => "76135",
39
+ :city => "Karlsruhe",
40
+ :street => {
41
+ :name_and_number => "Ernst-Frey-Str. 10"
42
+ }
43
+ },
44
+ :phones => {
45
+ :phone => [
46
+ { :number => "20333232", :provider => "171", :country => "+49" },
47
+ "+494534520085285",
48
+ "+494534523453453"
49
+ ]
50
+ }
51
+ }
52
+ }
53
+ end
54
+
55
+ it "should be possible to" do
56
+ @doc.simplify("/user").should == {
57
+ :address => {
58
+ :country => "Deutschland",
59
+ :zip_code => "76135",
60
+ :city => "Karlsruhe",
61
+ :street => {
62
+ :name_and_number => "Ernst-Frey-Str. 10"
63
+ }
64
+ },
65
+ :phones => {
66
+ :phone => [
67
+ { :number => "20333232", :provider => "171", :country => "+49" },
68
+ "+494534520085285",
69
+ "+494534523453453"
70
+ ]
71
+ }
72
+ }
73
+ end
74
+
75
+ it "should be possible to request for attributes of a not existing node" do
76
+ @doc.simplify_attributes("/test").should == nil
77
+ end
78
+
79
+ it "should be possible to request for existing attributes" do
80
+ @doc.simplify_attributes("/user/phones/phone[1]").should == {
81
+ :type => "MOBILE"
82
+ }
83
+ @doc.simplify_attributes("/user/phones/phone[2]").should == {
84
+ :type => "HOME"
85
+ }
86
+ @doc.simplify_attributes("/user/address/country").should == {
87
+ :iso_code => "de",
88
+ :nationality => "deutsch"
89
+ }
90
+ end
91
+ end
@@ -0,0 +1,2 @@
1
+ require "rspec"
2
+ require File.join(File.dirname(__FILE__), "..", "lib", "simple_xml")
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple-xml
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 1.0.0
6
+ platform: ruby
7
+ authors:
8
+ - Vincent Landgraf
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-11-21 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: "2.1"
24
+ type: :development
25
+ version_requirements: *id001
26
+ description: Some helpers for REXML::Element to create hashes from xml easily.
27
+ email: vilandgr+simplexml@googlemail.com
28
+ executables: []
29
+
30
+ extensions: []
31
+
32
+ extra_rdoc_files: []
33
+
34
+ files:
35
+ - Rakefile
36
+ - README.md
37
+ - simple-xml.gemspec
38
+ - lib/simple_xml.rb
39
+ - lib/simple_xml/simplifyer.rb
40
+ - lib/simple_xml/version.rb
41
+ - spec/simple_xml_spec.rb
42
+ - spec/spec_helper.rb
43
+ homepage: https://github.com/threez/simple-xml
44
+ licenses: []
45
+
46
+ post_install_message:
47
+ rdoc_options: []
48
+
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ requirements: []
64
+
65
+ rubyforge_project:
66
+ rubygems_version: 1.8.9
67
+ signing_key:
68
+ specification_version: 3
69
+ summary: Some helpers for REXML::Element to create hashes from xml easily
70
+ test_files:
71
+ - spec/simple_xml_spec.rb
72
+ - spec/spec_helper.rb