rsxml 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +5 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +38 -0
- data/LICENSE.txt +1 -1
- data/README.md +122 -0
- data/Rakefile +21 -20
- data/VERSION +1 -1
- data/rsxml.gemspec +84 -0
- data/spec/rsxml/namespace_spec.rb +17 -16
- data/spec/rsxml/sexp_spec.rb +1 -0
- data/spec/rsxml/util_spec.rb +1 -0
- data/spec/rsxml/visitor_spec.rb +20 -18
- data/spec/rsxml/xml_spec.rb +2 -1
- data/spec/rsxml_spec.rb +13 -12
- data/spec/spec_helper.rb +3 -9
- metadata +144 -112
- data/README.rdoc +0 -102
data/.travis.yml
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gem "nokogiri", "~> 1.5.8"
|
4
|
+
gem "builder", "~> 3.2.0"
|
5
|
+
|
6
|
+
group :development do
|
7
|
+
gem "rake", "~> 10.0.3"
|
8
|
+
gem "rspec", "~> 2.13.0"
|
9
|
+
gem "rdoc", "~> 4.0.0"
|
10
|
+
gem "bundler", "~> 1.3.2"
|
11
|
+
gem "jeweler", "~> 1.8.4"
|
12
|
+
# gem "rcov", ">= 0"
|
13
|
+
gem 'rr', ">= 1.0.4"
|
14
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
builder (3.2.0)
|
5
|
+
diff-lcs (1.2.1)
|
6
|
+
git (1.2.5)
|
7
|
+
jeweler (1.8.4)
|
8
|
+
bundler (~> 1.0)
|
9
|
+
git (>= 1.2.5)
|
10
|
+
rake
|
11
|
+
rdoc
|
12
|
+
json (1.7.7)
|
13
|
+
nokogiri (1.5.8)
|
14
|
+
rake (10.0.3)
|
15
|
+
rdoc (4.0.0)
|
16
|
+
json (~> 1.4)
|
17
|
+
rr (1.0.4)
|
18
|
+
rspec (2.13.0)
|
19
|
+
rspec-core (~> 2.13.0)
|
20
|
+
rspec-expectations (~> 2.13.0)
|
21
|
+
rspec-mocks (~> 2.13.0)
|
22
|
+
rspec-core (2.13.1)
|
23
|
+
rspec-expectations (2.13.0)
|
24
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
25
|
+
rspec-mocks (2.13.0)
|
26
|
+
|
27
|
+
PLATFORMS
|
28
|
+
ruby
|
29
|
+
|
30
|
+
DEPENDENCIES
|
31
|
+
builder (~> 3.2.0)
|
32
|
+
bundler (~> 1.3.2)
|
33
|
+
jeweler (~> 1.8.4)
|
34
|
+
nokogiri (~> 1.5.8)
|
35
|
+
rake (~> 10.0.3)
|
36
|
+
rdoc (~> 4.0.0)
|
37
|
+
rr (>= 1.0.4)
|
38
|
+
rspec (~> 2.13.0)
|
data/LICENSE.txt
CHANGED
data/README.md
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
rsxml [![Build Status](https://travis-ci.org/mccraigmccraig/rsxml.png?branch=master)](https://travis-ci.org/mccraigmccraig/rsxml)
|
2
|
+
=====
|
3
|
+
|
4
|
+
Ruby literal representation of XML documents in the style of [SXML](http://en.wikipedia.org/wiki/SXML)
|
5
|
+
|
6
|
+
Installation
|
7
|
+
------------
|
8
|
+
|
9
|
+
$ gem install rsxml
|
10
|
+
|
11
|
+
|
12
|
+
Background
|
13
|
+
----------
|
14
|
+
|
15
|
+
Rsxml is a Ruby library to translate XML documents into an s-expression style Ruby literal representation, using Array and Hash literals, and back again
|
16
|
+
|
17
|
+
Why would you want to do this ? Ruby literals :
|
18
|
+
|
19
|
+
* can be == compared natively
|
20
|
+
* are easy to read
|
21
|
+
* can be indented nicely by editors
|
22
|
+
* can be syntax checked and balanced by editors
|
23
|
+
|
24
|
+
These features make them nice for writing readable XML generation code and readable tests for XML generating code
|
25
|
+
|
26
|
+
Rsxml uses [Nokogiri](http://nokogiri.org/) for parsing XML, and [Builder](http://builder.rubyforge.org/) for generating it. Rsxml is not a feature complete XML processor : It does not attempt to process PIs, CDATA etc, but it does make it very easy to use and generate straightforward XML documents from Ruby
|
27
|
+
|
28
|
+
Use
|
29
|
+
---
|
30
|
+
|
31
|
+
Rsxml represents XML documents as s-expressions comprised of Ruby Array and Hash literals, thus :
|
32
|
+
|
33
|
+
["Foo", {"foofoo"=>"10"}, ["Bar", "barbar"], ["Baz"]]
|
34
|
+
|
35
|
+
represents the XML document :
|
36
|
+
|
37
|
+
<Foo foofoo="10"><Bar>barbar</Bar><Baz></Baz></Foo>
|
38
|
+
|
39
|
+
It is easy to convert XML docuemnts to Rsxml representation and back again :
|
40
|
+
|
41
|
+
xml = Rsxml.to_xml(["Foo", {"foofoo"=>"10"}, ["Bar", "barbar"]])
|
42
|
+
=> '<Foo foofoo="10"><Bar>barbar</Bar></Foo>'
|
43
|
+
|
44
|
+
Rsxml.to_rsxml(xml)
|
45
|
+
=> ["Foo", {"foofoo"=>"10"}, ["Bar", "barbar"]]
|
46
|
+
|
47
|
+
### Namespaces
|
48
|
+
|
49
|
+
XML namespaces are dealt with straightforwardly. When an XML document is converted to Rsxml, namespaces are preserved, and you can specify namespaces in an Rsxml structure in two ways, which can be freely mixed
|
50
|
+
|
51
|
+
* using QName prefixes and declarative attributes, exactly as with XML
|
52
|
+
* using exploded QNames consisting of <tt>[local_part, prefix, uri]</tt> triples and <tt>[local_part, prefix]</tt> pairs
|
53
|
+
|
54
|
+
### Converting to Rsxml
|
55
|
+
|
56
|
+
|
57
|
+
When you convert an XML document to Rsxml you can choose either <tt>:xml</tt> or <tt>:exploded</tt> style
|
58
|
+
|
59
|
+
#### <tt>:xml</tt> style
|
60
|
+
|
61
|
+
In <tt>:xml</tt> style namespaces are declared using attributes, and namespaces are referenced using
|
62
|
+
`prefix:LocalPart` QNames, as in XML
|
63
|
+
|
64
|
+
Rsxml.to_rsxml('<foo:foofoo xmlns:foo="http://foo.com/foo" foo:bar="barbar"/>', :style=>:xml)
|
65
|
+
=> ["foo:foofoo", {"foo:bar"=>"barbar", "xmlns:foo"=>"http://foo.com/foo"}]
|
66
|
+
|
67
|
+
#### <tt>:exploded</tt> style
|
68
|
+
|
69
|
+
In <tt>:exploded</tt> style namespaces are not declared using attributes, and QNames are specified
|
70
|
+
using <tt>[local_part, prefix, uri]</tt> triples
|
71
|
+
|
72
|
+
Rsxml.to_rsxml('<foo:foofoo xmlns:foo="http://foo.com/foo" foo:bar="barbar"/>', :style=>:exploded)
|
73
|
+
=> [["foofoo", "foo", "http://foo.com/foo"], {["bar", "foo", "http://foo.com/foo"]=>"barbar"}]
|
74
|
+
|
75
|
+
### Converting to XML
|
76
|
+
|
77
|
+
Rsxml styles can be mixed, and replicated namespace references can be skipped (i.e. `[local_part,prefix]` pairs can be used instead of `[local_part, prefix, uri]` triples) for readability
|
78
|
+
|
79
|
+
Rsxml.to_xml([["foofoo", "foo", "http://foo.com/foo"], {"foo:bar"=>"1", ["baz", "foo"]=>"2"}])
|
80
|
+
=> '<foo:foofoo foo:baz="2" foo:bar="1" xmlns:foo="http://foo.com/foo"></foo:foofoo>'
|
81
|
+
|
82
|
+
### Fragments
|
83
|
+
|
84
|
+
XML Fragments, without proper namespace declarations, can be parsed by passing a Hash of namespace
|
85
|
+
prefix bindings
|
86
|
+
|
87
|
+
Rsxml.to_rsxml('<foo:foofoo foo:bar="barbar"/>', :ns=>{"foo"=>"http://foo.com/foo"}, :style=>:xml)
|
88
|
+
=> ["foo:foofoo", {"foo:bar"=>"barbar"}]
|
89
|
+
|
90
|
+
Fragments can be generated similarly :
|
91
|
+
|
92
|
+
Rsxml.to_xml(["foo:foofoo", {"foo:bar"=>"barbar"}], :ns=>{"foo"=>"http://foo.com/foo"})
|
93
|
+
=> '<foo:foofoo foo:bar="barbar"></foo:foofoo>'
|
94
|
+
|
95
|
+
### Visitors
|
96
|
+
|
97
|
+
<tt>Rsxml.to_rsxml</tt> and <tt>Rsxml.to_xml</tt> are implemented with a simple Visitor pattern over the XML document structure. <tt>Rsxml::Sexp.traverse()</tt> traverses a Rsxml s-expression representation of an XML document and <tt>Rsxml::Xml.traverse()</tt> traverses a Nokogiri Node tree. The Visitor receives a
|
98
|
+
|
99
|
+
text(context, text)
|
100
|
+
|
101
|
+
invocation for each text node, and an
|
102
|
+
|
103
|
+
element(context, name, attrs, ns_decls)
|
104
|
+
|
105
|
+
method invocation for each element. If namespaces are used, element and attribute names in the <tt>element</tt> method invocations are exploded <tt>[local_part, prefix, uri]</tt> triples. The attributes are presented as a <tt>{name=>value}</tt> `Hash` which contains no namespace-related attributes. Any namespace declarations for the element are provided as the <tt>{prefix=>uri}</tt> `ns_decls` `Hash`. Namespace prefixes, URIs and declaration attributes are cleanly separated in this API, so it is easy for Visitor implementations to correctly process XML documents with namespaces
|
106
|
+
|
107
|
+
Contributing to rsxml
|
108
|
+
---------------------
|
109
|
+
|
110
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
111
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
112
|
+
* Fork the project
|
113
|
+
* Start a feature/bugfix branch
|
114
|
+
* Commit and push until you are happy with your contribution
|
115
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
116
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
117
|
+
|
118
|
+
Copyright
|
119
|
+
---------
|
120
|
+
|
121
|
+
Copyright (c) 2012 mccraigmccraig of the clan mccraig. See LICENSE.txt for
|
122
|
+
further details.
|
data/Rakefile
CHANGED
@@ -1,4 +1,14 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
2
12
|
require 'rake'
|
3
13
|
|
4
14
|
require 'jeweler'
|
@@ -11,38 +21,29 @@ Jeweler::Tasks.new do |gem|
|
|
11
21
|
gem.description = %Q{convert XML documents to an s-expression representation and back again in Ruby}
|
12
22
|
gem.email = "craig@trampolinesystems.com"
|
13
23
|
gem.authors = ["Trampoline Systems Ltd"]
|
14
|
-
#
|
15
|
-
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
16
|
-
gem.add_runtime_dependency "nokogiri", ">= 1.4.4"
|
17
|
-
gem.add_development_dependency "rspec", "~> 1.3.1"
|
18
|
-
gem.add_development_dependency "rr", ">= 0.10.5"
|
19
|
-
gem.add_development_dependency "jeweler", "~> 1.5.2"
|
20
|
-
gem.add_development_dependency "rcov", ">= 0"
|
24
|
+
# dependencies defined in Gemfile
|
21
25
|
end
|
22
26
|
Jeweler::RubygemsDotOrgTasks.new
|
23
27
|
|
24
|
-
require '
|
25
|
-
|
26
|
-
|
27
|
-
spec.
|
28
|
-
end
|
29
|
-
|
30
|
-
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
31
|
-
spec.libs << 'lib' << 'spec'
|
32
|
-
spec.pattern = 'spec/**/*_spec.rb'
|
33
|
-
spec.rcov = true
|
28
|
+
require 'rspec/core'
|
29
|
+
require 'rspec/core/rake_task'
|
30
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
31
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
34
32
|
end
|
35
33
|
|
36
|
-
|
34
|
+
# RSpec::Core::RakeTask.new(:rcov) do |spec|
|
35
|
+
# spec.pattern = 'spec/**/*_spec.rb'
|
36
|
+
# spec.rcov = true
|
37
|
+
# end
|
37
38
|
|
38
39
|
task :default => :spec
|
39
40
|
|
40
|
-
require '
|
41
|
+
require 'rdoc/task'
|
41
42
|
Rake::RDocTask.new do |rdoc|
|
42
43
|
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
43
44
|
|
44
45
|
rdoc.rdoc_dir = 'rdoc'
|
45
|
-
rdoc.title = "
|
46
|
+
rdoc.title = "mdquery #{version}"
|
46
47
|
rdoc.rdoc_files.include('README*')
|
47
48
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
48
49
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
data/rsxml.gemspec
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "rsxml"
|
8
|
+
s.version = "0.4.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Trampoline Systems Ltd"]
|
12
|
+
s.date = "2013-03-21"
|
13
|
+
s.description = "convert XML documents to an s-expression representation and back again in Ruby"
|
14
|
+
s.email = "craig@trampolinesystems.com"
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.md"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".rspec",
|
22
|
+
".travis.yml",
|
23
|
+
"Gemfile",
|
24
|
+
"Gemfile.lock",
|
25
|
+
"LICENSE.txt",
|
26
|
+
"README.md",
|
27
|
+
"Rakefile",
|
28
|
+
"VERSION",
|
29
|
+
"lib/rsxml.rb",
|
30
|
+
"lib/rsxml/namespace.rb",
|
31
|
+
"lib/rsxml/sexp.rb",
|
32
|
+
"lib/rsxml/util.rb",
|
33
|
+
"lib/rsxml/visitor.rb",
|
34
|
+
"lib/rsxml/xml.rb",
|
35
|
+
"rsxml.gemspec",
|
36
|
+
"spec/rsxml/mock_visitor.rb",
|
37
|
+
"spec/rsxml/namespace_spec.rb",
|
38
|
+
"spec/rsxml/sexp_spec.rb",
|
39
|
+
"spec/rsxml/util_spec.rb",
|
40
|
+
"spec/rsxml/visitor_spec.rb",
|
41
|
+
"spec/rsxml/xml_spec.rb",
|
42
|
+
"spec/rsxml_spec.rb",
|
43
|
+
"spec/spec_helper.rb"
|
44
|
+
]
|
45
|
+
s.homepage = "http://github.com/trampoline/rsxml"
|
46
|
+
s.licenses = ["MIT"]
|
47
|
+
s.require_paths = ["lib"]
|
48
|
+
s.rubygems_version = "1.8.23"
|
49
|
+
s.summary = "an s-expression representation of XML documents in Ruby"
|
50
|
+
|
51
|
+
if s.respond_to? :specification_version then
|
52
|
+
s.specification_version = 3
|
53
|
+
|
54
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
55
|
+
s.add_runtime_dependency(%q<nokogiri>, ["~> 1.5.8"])
|
56
|
+
s.add_runtime_dependency(%q<builder>, ["~> 3.2.0"])
|
57
|
+
s.add_development_dependency(%q<rake>, ["~> 10.0.3"])
|
58
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.13.0"])
|
59
|
+
s.add_development_dependency(%q<rdoc>, ["~> 4.0.0"])
|
60
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.3.2"])
|
61
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
|
62
|
+
s.add_development_dependency(%q<rr>, [">= 1.0.4"])
|
63
|
+
else
|
64
|
+
s.add_dependency(%q<nokogiri>, ["~> 1.5.8"])
|
65
|
+
s.add_dependency(%q<builder>, ["~> 3.2.0"])
|
66
|
+
s.add_dependency(%q<rake>, ["~> 10.0.3"])
|
67
|
+
s.add_dependency(%q<rspec>, ["~> 2.13.0"])
|
68
|
+
s.add_dependency(%q<rdoc>, ["~> 4.0.0"])
|
69
|
+
s.add_dependency(%q<bundler>, ["~> 1.3.2"])
|
70
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
71
|
+
s.add_dependency(%q<rr>, [">= 1.0.4"])
|
72
|
+
end
|
73
|
+
else
|
74
|
+
s.add_dependency(%q<nokogiri>, ["~> 1.5.8"])
|
75
|
+
s.add_dependency(%q<builder>, ["~> 3.2.0"])
|
76
|
+
s.add_dependency(%q<rake>, ["~> 10.0.3"])
|
77
|
+
s.add_dependency(%q<rspec>, ["~> 2.13.0"])
|
78
|
+
s.add_dependency(%q<rdoc>, ["~> 4.0.0"])
|
79
|
+
s.add_dependency(%q<bundler>, ["~> 1.3.2"])
|
80
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
81
|
+
s.add_dependency(%q<rr>, [">= 1.0.4"])
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require File.expand_path("../../spec_helper", __FILE__)
|
2
|
+
require 'rsxml/namespace'
|
2
3
|
|
3
4
|
module Rsxml
|
4
5
|
describe "find_namespace_uri" do
|
@@ -60,7 +61,7 @@ module Rsxml
|
|
60
61
|
end
|
61
62
|
|
62
63
|
it "should unqualify an unprefixed name in the default namespace" do
|
63
|
-
Namespace.explode_qname([{""=>"http://foo.com/foo"}], "bar").should ==
|
64
|
+
Namespace.explode_qname([{""=>"http://foo.com/foo"}], "bar").should ==
|
64
65
|
["bar", "", "http://foo.com/foo"]
|
65
66
|
end
|
66
67
|
|
@@ -123,20 +124,20 @@ module Rsxml
|
|
123
124
|
|
124
125
|
describe "compact_qname" do
|
125
126
|
it "should produce a qname from a pair or triple" do
|
126
|
-
Namespace.compact_qname([{"foo"=>"http://foo.com/foo"}],
|
127
|
+
Namespace.compact_qname([{"foo"=>"http://foo.com/foo"}],
|
127
128
|
["bar", "foo"]).should ==
|
128
129
|
"foo:bar"
|
129
|
-
Namespace.compact_qname([{"foo"=>"http://foo.com/foo"}],
|
130
|
+
Namespace.compact_qname([{"foo"=>"http://foo.com/foo"}],
|
130
131
|
["bar", "foo", "http://foo.com/foo"]).should ==
|
131
132
|
"foo:bar"
|
132
133
|
end
|
133
134
|
|
134
135
|
it "should produce a qname with default namespace" do
|
135
|
-
Namespace.compact_qname([{""=>"http://foo.com/foo"}],
|
136
|
+
Namespace.compact_qname([{""=>"http://foo.com/foo"}],
|
136
137
|
["bar", ""]).should ==
|
137
138
|
"bar"
|
138
139
|
|
139
|
-
Namespace.compact_qname([{""=>"http://foo.com/foo"}],
|
140
|
+
Namespace.compact_qname([{""=>"http://foo.com/foo"}],
|
140
141
|
["bar", "", "http://foo.com/foo"]).should ==
|
141
142
|
"bar"
|
142
143
|
end
|
@@ -153,21 +154,21 @@ module Rsxml
|
|
153
154
|
|
154
155
|
it "should raise an error if a prefix is not bound" do
|
155
156
|
lambda {
|
156
|
-
Namespace.compact_qname([],
|
157
|
+
Namespace.compact_qname([],
|
157
158
|
["bar", "foo", "http://foo.com/foo"])
|
158
159
|
}.should raise_error(/not bound/)
|
159
160
|
end
|
160
161
|
|
161
162
|
it "should raise an error if a prefix binding clashes" do
|
162
163
|
lambda {
|
163
|
-
Namespace.compact_qname([{"foo"=>"http://foo.com/foo"}],
|
164
|
+
Namespace.compact_qname([{"foo"=>"http://foo.com/foo"}],
|
164
165
|
["bar", "foo", "http://bar.com/bar"])
|
165
166
|
}.should raise_error(/'foo' is bound/)
|
166
167
|
end
|
167
168
|
|
168
169
|
it "should raise an error if default namespace binding clashes" do
|
169
170
|
lambda {
|
170
|
-
Namespace.compact_qname([{""=>"http://foo.com/foo"}],
|
171
|
+
Namespace.compact_qname([{""=>"http://foo.com/foo"}],
|
171
172
|
["bar", "", "http://bar.com/bar"])
|
172
173
|
}.should raise_error(/'' is bound/)
|
173
174
|
end
|
@@ -235,22 +236,22 @@ module Rsxml
|
|
235
236
|
|
236
237
|
describe "exploded_namespace_declarations" do
|
237
238
|
it "should produce unqalified namespaces declarations" do
|
238
|
-
Namespace.exploded_namespace_declarations({""=>"http://default.com/default", "foo"=>"http://foo.com/foo"}).should ==
|
239
|
+
Namespace.exploded_namespace_declarations({""=>"http://default.com/default", "foo"=>"http://foo.com/foo"}).should ==
|
239
240
|
{"xmlns"=>"http://default.com/default", ["foo", "xmlns"]=>"http://foo.com/foo"}
|
240
241
|
end
|
241
242
|
end
|
242
243
|
|
243
244
|
describe "namespace_attributes" do
|
244
245
|
it "should produce a Hash of namespace declaration attributes" do
|
245
|
-
Namespace.namespace_attributes({""=>"http://default.com/default", "foo"=>"http://foo.com/foo"}).should ==
|
246
|
+
Namespace.namespace_attributes({""=>"http://default.com/default", "foo"=>"http://foo.com/foo"}).should ==
|
246
247
|
{"xmlns"=>"http://default.com/default", "xmlns:foo"=>"http://foo.com/foo"}
|
247
248
|
end
|
248
249
|
end
|
249
250
|
|
250
251
|
describe "non_ns_attrs_ns_bindings" do
|
251
252
|
it "should extract non-ns attributes and explicit namespace bindings" do
|
252
|
-
Namespace.non_ns_attrs_ns_bindings([{"foo"=>"http://foo.com/foo"}],
|
253
|
-
[:bar, "foo", "http://foo.com/foo"],
|
253
|
+
Namespace.non_ns_attrs_ns_bindings([{"foo"=>"http://foo.com/foo"}],
|
254
|
+
[:bar, "foo", "http://foo.com/foo"],
|
254
255
|
{ "xmlns:boo"=>"http://boo.com/boo",
|
255
256
|
[:b, "bar", "http://bar.com/bar"]=>"barbar",
|
256
257
|
[:c, "baz", "http://baz.com/baz"]=>"bazbaz",
|
@@ -258,20 +259,20 @@ module Rsxml
|
|
258
259
|
[{[:b, "bar", "http://bar.com/bar"]=>"barbar",
|
259
260
|
[:c, "baz", "http://baz.com/baz"]=>"bazbaz",
|
260
261
|
[:d, "foo"]=>"booboo"},
|
261
|
-
{ "baz"=>"http://baz.com/baz",
|
262
|
+
{ "baz"=>"http://baz.com/baz",
|
262
263
|
"bar"=>"http://bar.com/bar",
|
263
264
|
"boo"=>"http://boo.com/boo"}]
|
264
265
|
end
|
265
266
|
|
266
267
|
it "should extract explicit default namespace bindings" do
|
267
|
-
Namespace.non_ns_attrs_ns_bindings([{"foo"=>"http://foo.com/foo"}],
|
268
|
-
[:bar, "", "http://default.com/default"],
|
268
|
+
Namespace.non_ns_attrs_ns_bindings([{"foo"=>"http://foo.com/foo"}],
|
269
|
+
[:bar, "", "http://default.com/default"],
|
269
270
|
{ [:d, "foo"]=>"booboo"}).should ==
|
270
271
|
[{ [:d, "foo"]=>"booboo"},
|
271
272
|
{ ""=>"http://default.com/default"}]
|
272
273
|
end
|
273
274
|
|
274
|
-
|
275
|
+
|
275
276
|
end
|
276
277
|
|
277
278
|
end
|
data/spec/rsxml/sexp_spec.rb
CHANGED
data/spec/rsxml/util_spec.rb
CHANGED
data/spec/rsxml/visitor_spec.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require File.expand_path("../../spec_helper", __FILE__)
|
2
|
+
require 'rsxml/visitor'
|
3
|
+
require 'rsxml/mock_visitor'
|
2
4
|
|
3
5
|
module Rsxml
|
4
6
|
# tests traverse methods on both Xml and Sexp together : they should produce identical visitation
|
@@ -9,7 +11,7 @@ module Rsxml
|
|
9
11
|
xml_root = Nokogiri::XML(xml).children.first
|
10
12
|
Xml.traverse(xml_root, xml_visitor)
|
11
13
|
xml_visitor.__finalize__
|
12
|
-
|
14
|
+
|
13
15
|
sexp_visitor = Visitor::MockVisitor.new(expectations)
|
14
16
|
Sexp.traverse(sexp, sexp_visitor)
|
15
17
|
sexp_visitor.__finalize__
|
@@ -22,18 +24,18 @@ module Rsxml
|
|
22
24
|
end
|
23
25
|
|
24
26
|
it "should call the element function on the visitor with exploded element and attributes qnames" do
|
25
|
-
check_traverse([[:element, :_,
|
26
|
-
["foofoo", "foo", "http://foo.com/foo"],
|
27
|
-
{["bar", "foo", "http://foo.com/foo"]=>"barbar"},
|
27
|
+
check_traverse([[:element, :_,
|
28
|
+
["foofoo", "foo", "http://foo.com/foo"],
|
29
|
+
{["bar", "foo", "http://foo.com/foo"]=>"barbar"},
|
28
30
|
{"foo"=>"http://foo.com/foo"}]],
|
29
31
|
'<foo:foofoo foo:bar="barbar" xmlns:foo="http://foo.com/foo"/>',
|
30
32
|
[["foofoo", "foo"], {["bar", "foo", "http://foo.com/foo"]=>"barbar"}])
|
31
33
|
end
|
32
34
|
|
33
35
|
it "should call the test function on the visitor with textual content" do
|
34
|
-
check_traverse([[:element, :_,
|
35
|
-
["foofoo", "foo", "http://foo.com/foo"],
|
36
|
-
{["bar", "foo", "http://foo.com/foo"]=>"barbar"},
|
36
|
+
check_traverse([[:element, :_,
|
37
|
+
["foofoo", "foo", "http://foo.com/foo"],
|
38
|
+
{["bar", "foo", "http://foo.com/foo"]=>"barbar"},
|
37
39
|
{"foo"=>"http://foo.com/foo"}],
|
38
40
|
[:text, :_, "boohoo"]],
|
39
41
|
'<foo:foofoo foo:bar="barbar" xmlns:foo="http://foo.com/foo">boohoo</foo:foofoo>',
|
@@ -41,9 +43,9 @@ module Rsxml
|
|
41
43
|
end
|
42
44
|
|
43
45
|
it "should call the element function in document order for each element in a hierarchic doc" do
|
44
|
-
check_traverse([[:element, :_,
|
45
|
-
["foofoo", "foo", "http://foo.com/foo"],
|
46
|
-
{["bar", "foo", "http://foo.com/foo"]=>"barbar"},
|
46
|
+
check_traverse([[:element, :_,
|
47
|
+
["foofoo", "foo", "http://foo.com/foo"],
|
48
|
+
{["bar", "foo", "http://foo.com/foo"]=>"barbar"},
|
47
49
|
{"foo"=>"http://foo.com/foo"}],
|
48
50
|
[:element, :_,
|
49
51
|
["barbar", "foo", "http://foo.com/foo"],
|
@@ -55,9 +57,9 @@ module Rsxml
|
|
55
57
|
end
|
56
58
|
|
57
59
|
it "should call the element/text functions in a mixed document in document order" do
|
58
|
-
check_traverse([[:element, :_,
|
59
|
-
["foofoo", "foo", "http://foo.com/foo"],
|
60
|
-
{["bar", "foo", "http://foo.com/foo"]=>"barbar"},
|
60
|
+
check_traverse([[:element, :_,
|
61
|
+
["foofoo", "foo", "http://foo.com/foo"],
|
62
|
+
{["bar", "foo", "http://foo.com/foo"]=>"barbar"},
|
61
63
|
{"foo"=>"http://foo.com/foo"}],
|
62
64
|
[:element, :_,
|
63
65
|
["barbar", "foo", "http://foo.com/foo"],
|
@@ -76,9 +78,9 @@ module Rsxml
|
|
76
78
|
end
|
77
79
|
|
78
80
|
it "should work the same with compact sexp representations" do
|
79
|
-
check_traverse([[:element, :_,
|
80
|
-
["foofoo", "foo", "http://foo.com/foo"],
|
81
|
-
{["bar", "foo", "http://foo.com/foo"]=>"barbar"},
|
81
|
+
check_traverse([[:element, :_,
|
82
|
+
["foofoo", "foo", "http://foo.com/foo"],
|
83
|
+
{["bar", "foo", "http://foo.com/foo"]=>"barbar"},
|
82
84
|
{"foo"=>"http://foo.com/foo"}],
|
83
85
|
[:element, :_,
|
84
86
|
["barbar", "foo", "http://foo.com/foo"],
|
@@ -181,7 +183,7 @@ module Rsxml
|
|
181
183
|
cattrs = Hash[attrs.map{|n,v| [capitalize_local_part(n), v]}]
|
182
184
|
[celement_name, cattrs]
|
183
185
|
end ).sexp
|
184
|
-
|
186
|
+
|
185
187
|
rsxml.should ==
|
186
188
|
["Foo", {"Bar"=>"10", "Baz"=>"20"}]
|
187
189
|
|
@@ -191,7 +193,7 @@ module Rsxml
|
|
191
193
|
cattrs = Hash[attrs.map{|n,v| [capitalize_local_part(n), v]}]
|
192
194
|
[celement_name, cattrs]
|
193
195
|
end ).sexp
|
194
|
-
|
196
|
+
|
195
197
|
rsxml.should ==
|
196
198
|
[["Foo", "a", "http://a.com/a"], {"Bar"=>"10", "Baz"=>"20"}]
|
197
199
|
|
data/spec/rsxml/xml_spec.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require File.expand_path("../../spec_helper", __FILE__)
|
2
|
+
require 'rsxml/xml'
|
2
3
|
|
3
4
|
module Rsxml
|
4
5
|
describe "wrap_fragment" do
|
@@ -64,7 +65,7 @@ module Rsxml
|
|
64
65
|
|
65
66
|
eelement, eattrs = Rsxml::Xml.explode_element(root)
|
66
67
|
eelement.should == ["bar", "foo", "http://foo.com/foo"]
|
67
|
-
eattrs.should == {"a"=>"aa",
|
68
|
+
eattrs.should == {"a"=>"aa",
|
68
69
|
["b", "foo", "http://foo.com/foo"]=>"bb"}
|
69
70
|
end
|
70
71
|
end
|
data/spec/rsxml_spec.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
require 'rsxml'
|
2
3
|
|
3
4
|
describe Rsxml do
|
4
5
|
describe "to_xml" do
|
@@ -7,7 +8,7 @@ describe Rsxml do
|
|
7
8
|
end
|
8
9
|
|
9
10
|
it "should produce a single-element doc with namespaces" do
|
10
|
-
Rsxml.to_xml([[:bar, :foo, "http://foo.com/foo"]]).should ==
|
11
|
+
Rsxml.to_xml([[:bar, :foo, "http://foo.com/foo"]]).should ==
|
11
12
|
'<foo:bar xmlns:foo="http://foo.com/foo"></foo:bar>'
|
12
13
|
end
|
13
14
|
|
@@ -30,7 +31,7 @@ describe Rsxml do
|
|
30
31
|
r.name.should == "bar"
|
31
32
|
r.namespace.href.should == "http://foo.com/foo"
|
32
33
|
r.namespace.prefix.should == "foo"
|
33
|
-
|
34
|
+
|
34
35
|
r.attributes["bar"].namespace.should == nil
|
35
36
|
r["bar"].should == "1"
|
36
37
|
|
@@ -39,11 +40,11 @@ describe Rsxml do
|
|
39
40
|
end
|
40
41
|
|
41
42
|
it "should produce a single-element doc with namespace and attr namespaces" do
|
42
|
-
xml = Rsxml.to_xml([[:bar, :foo, "http://foo.com/foo"],
|
43
|
-
{[:barbar, :bar, "http://bar.com/bar"]=>1,
|
43
|
+
xml = Rsxml.to_xml([[:bar, :foo, "http://foo.com/foo"],
|
44
|
+
{[:barbar, :bar, "http://bar.com/bar"]=>1,
|
44
45
|
:baz=>"baz"}])
|
45
46
|
r = Nokogiri::XML(xml).children.first
|
46
|
-
|
47
|
+
|
47
48
|
r.name.should == "bar"
|
48
49
|
r.namespace.prefix.should == "foo"
|
49
50
|
r.namespace.href.should == "http://foo.com/foo"
|
@@ -59,11 +60,11 @@ describe Rsxml do
|
|
59
60
|
end
|
60
61
|
|
61
62
|
it "should produce a single-element doc with default namespace and attr namespaces" do
|
62
|
-
xml = Rsxml.to_xml([[:bar, "", "http://foo.com/foo"],
|
63
|
-
{[:barbar, :bar, "http://bar.com/bar"]=>1,
|
63
|
+
xml = Rsxml.to_xml([[:bar, "", "http://foo.com/foo"],
|
64
|
+
{[:barbar, :bar, "http://bar.com/bar"]=>1,
|
64
65
|
:baz=>"baz"}])
|
65
66
|
r = Nokogiri::XML(xml).children.first
|
66
|
-
|
67
|
+
|
67
68
|
r.name.should == "bar"
|
68
69
|
r.namespace.prefix.should == nil
|
69
70
|
r.namespace.href.should == "http://foo.com/foo"
|
@@ -123,11 +124,11 @@ describe Rsxml do
|
|
123
124
|
r.namespace.href.should == "http://foo.com/foo"
|
124
125
|
r.namespace.prefix.should == "foo"
|
125
126
|
|
126
|
-
r["bar"].should == "1"
|
127
|
+
r["foo:bar"].should == "1"
|
127
128
|
r.attributes["bar"].namespace.href.should == "http://foo.com/foo"
|
128
129
|
r.attributes["bar"].namespace.prefix.should == "foo"
|
129
130
|
|
130
|
-
r["baz"].should == "baz"
|
131
|
+
r["foo:baz"].should == "baz"
|
131
132
|
r.attributes["baz"].namespace.href.should == "http://foo.com/foo"
|
132
133
|
r.attributes["baz"].namespace.prefix.should == "foo"
|
133
134
|
end
|
@@ -135,12 +136,12 @@ describe Rsxml do
|
|
135
136
|
|
136
137
|
describe "to_rsxml" do
|
137
138
|
|
138
|
-
def test_roundtrip(org)
|
139
|
+
def test_roundtrip(org)
|
139
140
|
xml = Rsxml.to_xml(org)
|
140
141
|
rsxml = Rsxml.to_rsxml(xml, :style=>:xml)
|
141
142
|
rsxml.should == org
|
142
143
|
end
|
143
|
-
|
144
|
+
|
144
145
|
it "should parse a single-element doc" do
|
145
146
|
test_roundtrip(["foo"])
|
146
147
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,13 +1,7 @@
|
|
1
1
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
2
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
-
require '
|
4
|
-
require 'spec'
|
5
|
-
require 'spec/autorun'
|
6
|
-
require 'rr'
|
7
|
-
require 'nokogiri'
|
8
|
-
require 'rsxml'
|
9
|
-
require 'rsxml/mock_visitor'
|
3
|
+
require 'rspec'
|
10
4
|
|
11
|
-
|
12
|
-
config.mock_with
|
5
|
+
RSpec.configure do |config|
|
6
|
+
config.mock_with :rr
|
13
7
|
end
|
metadata
CHANGED
@@ -1,115 +1,160 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: rsxml
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 3
|
9
|
-
- 0
|
10
|
-
version: 0.3.0
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Trampoline Systems Ltd
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
dependencies:
|
21
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2013-03-21 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
22
15
|
name: nokogiri
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.5.8
|
22
|
+
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
|
25
|
-
none: false
|
26
|
-
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.5.8
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: builder
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 3.2.0
|
35
38
|
type: :runtime
|
36
|
-
|
37
|
-
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 3.2.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rake
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 10.0.3
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 10.0.3
|
62
|
+
- !ruby/object:Gem::Dependency
|
38
63
|
name: rspec
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 2.13.0
|
70
|
+
type: :development
|
39
71
|
prerelease: false
|
40
|
-
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 2.13.0
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rdoc
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
41
81
|
none: false
|
42
|
-
requirements:
|
82
|
+
requirements:
|
43
83
|
- - ~>
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
|
46
|
-
segments:
|
47
|
-
- 1
|
48
|
-
- 3
|
49
|
-
- 1
|
50
|
-
version: 1.3.1
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 4.0.0
|
51
86
|
type: :development
|
52
|
-
version_requirements: *id002
|
53
|
-
- !ruby/object:Gem::Dependency
|
54
|
-
name: rr
|
55
87
|
prerelease: false
|
56
|
-
|
57
|
-
none: false
|
58
|
-
requirements:
|
59
|
-
- -
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 4.0.0
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: bundler
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 1.3.2
|
67
102
|
type: :development
|
68
|
-
version_requirements: *id003
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: jeweler
|
71
103
|
prerelease: false
|
72
|
-
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
105
|
none: false
|
74
|
-
requirements:
|
106
|
+
requirements:
|
75
107
|
- - ~>
|
76
|
-
- !ruby/object:Gem::Version
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 1.3.2
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: jeweler
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 1.8.4
|
83
118
|
type: :development
|
84
|
-
version_requirements: *id004
|
85
|
-
- !ruby/object:Gem::Dependency
|
86
|
-
name: rcov
|
87
119
|
prerelease: false
|
88
|
-
|
89
|
-
none: false
|
90
|
-
requirements:
|
91
|
-
- -
|
92
|
-
- !ruby/object:Gem::Version
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ~>
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: 1.8.4
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: rr
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: 1.0.4
|
97
134
|
type: :development
|
98
|
-
|
99
|
-
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: 1.0.4
|
142
|
+
description: convert XML documents to an s-expression representation and back again
|
143
|
+
in Ruby
|
100
144
|
email: craig@trampolinesystems.com
|
101
145
|
executables: []
|
102
|
-
|
103
146
|
extensions: []
|
104
|
-
|
105
|
-
extra_rdoc_files:
|
147
|
+
extra_rdoc_files:
|
106
148
|
- LICENSE.txt
|
107
|
-
- README.
|
108
|
-
files:
|
149
|
+
- README.md
|
150
|
+
files:
|
109
151
|
- .document
|
110
152
|
- .rspec
|
153
|
+
- .travis.yml
|
154
|
+
- Gemfile
|
155
|
+
- Gemfile.lock
|
111
156
|
- LICENSE.txt
|
112
|
-
- README.
|
157
|
+
- README.md
|
113
158
|
- Rakefile
|
114
159
|
- VERSION
|
115
160
|
- lib/rsxml.rb
|
@@ -118,6 +163,7 @@ files:
|
|
118
163
|
- lib/rsxml/util.rb
|
119
164
|
- lib/rsxml/visitor.rb
|
120
165
|
- lib/rsxml/xml.rb
|
166
|
+
- rsxml.gemspec
|
121
167
|
- spec/rsxml/mock_visitor.rb
|
122
168
|
- spec/rsxml/namespace_spec.rb
|
123
169
|
- spec/rsxml/sexp_spec.rb
|
@@ -126,46 +172,32 @@ files:
|
|
126
172
|
- spec/rsxml/xml_spec.rb
|
127
173
|
- spec/rsxml_spec.rb
|
128
174
|
- spec/spec_helper.rb
|
129
|
-
has_rdoc: true
|
130
175
|
homepage: http://github.com/trampoline/rsxml
|
131
|
-
licenses:
|
176
|
+
licenses:
|
132
177
|
- MIT
|
133
178
|
post_install_message:
|
134
179
|
rdoc_options: []
|
135
|
-
|
136
|
-
require_paths:
|
180
|
+
require_paths:
|
137
181
|
- lib
|
138
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
182
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
139
183
|
none: false
|
140
|
-
requirements:
|
141
|
-
- -
|
142
|
-
- !ruby/object:Gem::Version
|
143
|
-
|
144
|
-
segments:
|
184
|
+
requirements:
|
185
|
+
- - ! '>='
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
segments:
|
145
189
|
- 0
|
146
|
-
|
147
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
190
|
+
hash: -348830186680735748
|
191
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
148
192
|
none: false
|
149
|
-
requirements:
|
150
|
-
- -
|
151
|
-
- !ruby/object:Gem::Version
|
152
|
-
|
153
|
-
segments:
|
154
|
-
- 0
|
155
|
-
version: "0"
|
193
|
+
requirements:
|
194
|
+
- - ! '>='
|
195
|
+
- !ruby/object:Gem::Version
|
196
|
+
version: '0'
|
156
197
|
requirements: []
|
157
|
-
|
158
198
|
rubyforge_project:
|
159
|
-
rubygems_version: 1.
|
199
|
+
rubygems_version: 1.8.23
|
160
200
|
signing_key:
|
161
201
|
specification_version: 3
|
162
202
|
summary: an s-expression representation of XML documents in Ruby
|
163
|
-
test_files:
|
164
|
-
- spec/rsxml/mock_visitor.rb
|
165
|
-
- spec/rsxml/namespace_spec.rb
|
166
|
-
- spec/rsxml/sexp_spec.rb
|
167
|
-
- spec/rsxml/util_spec.rb
|
168
|
-
- spec/rsxml/visitor_spec.rb
|
169
|
-
- spec/rsxml/xml_spec.rb
|
170
|
-
- spec/rsxml_spec.rb
|
171
|
-
- spec/spec_helper.rb
|
203
|
+
test_files: []
|
data/README.rdoc
DELETED
@@ -1,102 +0,0 @@
|
|
1
|
-
= rsxml
|
2
|
-
|
3
|
-
A Ruby library to translate XML documents into an s-expression representation, and back again, in the style of SXML[http://en.wikipedia.org/wiki/SXML]
|
4
|
-
|
5
|
-
Why would you want to do this ? Well, s-expressions can be == compared natively in Ruby, are easy to read
|
6
|
-
and editors indent them nicely when embedded in code. These features make them very suitable for writing readable
|
7
|
-
XML generation code and readable tests for XML generating code
|
8
|
-
|
9
|
-
Rsxml uses Nokogiri[http://nokogiri.org/] for parsing XML, and Builder[http://builder.rubyforge.org/] to generate it. Rsxml is not intended to be a feature complete XML processor : It does not attempt to process PIs, CDATA etc, but it does make it very easy to use and generate straightforward XML documents from Ruby
|
10
|
-
|
11
|
-
Rsxml represents XML documents as s-expressions thus :
|
12
|
-
|
13
|
-
["Foo", {"foofoo"=>"10"}, ["Bar", "barbar"], ["Baz"]]
|
14
|
-
|
15
|
-
represents the XML document :
|
16
|
-
<Foo foofoo="10"><Bar>barbar</Bar><Baz></Baz></Foo>
|
17
|
-
|
18
|
-
It is easy to convert XML docuemnts to Rsxml representation and back again :
|
19
|
-
|
20
|
-
xml = Rsxml.to_xml(["Foo", {"foofoo"=>"10"}, ["Bar", "barbar"]])
|
21
|
-
=> '<Foo foofoo="10"><Bar>barbar</Bar></Foo>'
|
22
|
-
|
23
|
-
Rsxml.to_rsxml(xml)
|
24
|
-
=> ["Foo", {"foofoo"=>"10"}, ["Bar", "barbar"]]
|
25
|
-
|
26
|
-
=== Namespaces
|
27
|
-
|
28
|
-
XML namespaces are dealt with straightforwardly. When an XML document is converted to Rsxml, namespaces are preserved, and you can specify namespaces in an Rsxml structure in two ways, which can be freely mixed
|
29
|
-
* using QName prefixes and declarative attributes, exactly as with XML
|
30
|
-
* using exploded QNames consisting of <tt>[local_part, prefix, uri]</tt> triples and <tt>[local_part, prefix]</tt> pairs
|
31
|
-
|
32
|
-
=== Converting to Rsxml
|
33
|
-
|
34
|
-
When you convert an XML document to Rsxml you can choose either <tt>:xml</tt> or <tt>:exploded</tt> style
|
35
|
-
|
36
|
-
==== <tt>:xml</tt> style
|
37
|
-
|
38
|
-
In <tt>:xml</tt> style namespaces are declared using attributes, and namespaces are referenced using
|
39
|
-
prefixed QNames, just as in XML
|
40
|
-
|
41
|
-
Rsxml.to_rsxml('<foo:foofoo xmlns:foo="http://foo.com/foo" foo:bar="barbar"/>', :style=>:xml)
|
42
|
-
=> ["foo:foofoo", {"foo:bar"=>"barbar", "xmlns:foo"=>"http://foo.com/foo"}]
|
43
|
-
|
44
|
-
==== <tt>:exploded</tt> style
|
45
|
-
|
46
|
-
In <tt>:exploded</tt> style namespaces are not declared using attributes, and QNames are specified
|
47
|
-
using <tt>[local_part, prefix, uri]</tt> triples
|
48
|
-
|
49
|
-
Rsxml.to_rsxml('<foo:foofoo xmlns:foo="http://foo.com/foo" foo:bar="barbar"/>', :style=>:exploded)
|
50
|
-
=> [["foofoo", "foo", "http://foo.com/foo"], {["bar", "foo", "http://foo.com/foo"]=>"barbar"}]
|
51
|
-
|
52
|
-
=== Converting to XML
|
53
|
-
|
54
|
-
Rsxml styles can be mixed, and unnecessary namespace references can be skipped for readability
|
55
|
-
|
56
|
-
Rsxml.to_xml([["foofoo", "foo", "http://foo.com/foo"], {"foo:bar"=>"1", ["baz", "foo"]=>"2"}])
|
57
|
-
=> '<foo:foofoo foo:baz="2" foo:bar="1" xmlns:foo="http://foo.com/foo"></foo:foofoo>'
|
58
|
-
|
59
|
-
=== Fragments
|
60
|
-
|
61
|
-
XML Fragments, without proper namespace declarations, can be parsed by passing a Hash of namespace
|
62
|
-
prefix bindings
|
63
|
-
|
64
|
-
Rsxml.to_rsxml('<foo:foofoo foo:bar="barbar"/>', :ns=>{"foo"=>"http://foo.com/foo"}, :style=>:xml)
|
65
|
-
=> ["foo:foofoo", {"foo:bar"=>"barbar"}]
|
66
|
-
|
67
|
-
Fragments can be generated similarly :
|
68
|
-
|
69
|
-
Rsxml.to_xml(["foo:foofoo", {"foo:bar"=>"barbar"}], :ns=>{"foo"=>"http://foo.com/foo"})
|
70
|
-
=> '<foo:foofoo foo:bar="barbar"></foo:foofoo>'
|
71
|
-
|
72
|
-
== Visitors
|
73
|
-
|
74
|
-
<tt>Rsxml.to_rsxml</tt> and <tt>Rsxml.to_xml</tt> are implemented with a simple Visitor pattern over the XML document structure. <tt>Rsxml::Sexp.traverse()</tt> traverses a Rsxml s-expression representation of an XML document and <tt>Rsxml::Xml.traverse()</tt> traverses a Nokogiri Node tree. The Visitor receives a
|
75
|
-
|
76
|
-
text(context, text)
|
77
|
-
|
78
|
-
invocation for each text node, and an
|
79
|
-
|
80
|
-
element(context, name, attrs, ns_decls)
|
81
|
-
|
82
|
-
method invocation for each element. If namespaces are used, element and attribute names in the <tt>element</tt> method invocations are exploded <tt>[local_part, prefix, uri]</tt> triples. The attributes are presented as a <tt>{name=>value}</tt> +Hash+ which contains no namespace-related attributes. Any namespace declarations for the element are provided as the <tt>{prefix=>uri}</tt> +ns_decls+ +Hash+. Namespace prefixes, URIs and declaration attributes are cleanly separated in this API, so it is easy for Visitor implementations to correctly process XML documents with namespaces
|
83
|
-
|
84
|
-
== Install
|
85
|
-
|
86
|
-
gem install rsxml
|
87
|
-
|
88
|
-
== Contributing to rsxml
|
89
|
-
|
90
|
-
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
91
|
-
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
92
|
-
* Fork the project
|
93
|
-
* Start a feature/bugfix branch
|
94
|
-
* Commit and push until you are happy with your contribution
|
95
|
-
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
96
|
-
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
97
|
-
|
98
|
-
== Copyright
|
99
|
-
|
100
|
-
Copyright (c) 2011 Trampoline Systems Ltd. See LICENSE.txt for
|
101
|
-
further details.
|
102
|
-
|