dongbin-faster-xml-simple 0.6.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.
data/COPYING ADDED
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2006 Michael Koziarski
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in the
5
+ Software without restriction, including without limitation the rights to use,
6
+ copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
7
+ Software, and to permit persons to whom the Software is furnished to do so,
8
+ subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
17
+ AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,10 @@
1
+ FasterXmlSimple
2
+
3
+ FasterXS is intended to be a drop in replacement for the xml input functionality
4
+ from XmlSimple. Instead of using rexml, it uses libxml and the associated ruby
5
+ bindings. This reduces CPU utilisation and memory consumption considerably.
6
+
7
+ Preliminary benchmarks show it between 3 and 10 times as fast, and using a
8
+ fraction of the ram.
9
+
10
+
data/Rakefile ADDED
@@ -0,0 +1,54 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'lib/faster_xml_simple'
8
+
9
+ task :default => :test
10
+
11
+ Rake::TestTask.new do |test|
12
+ test.pattern = 'test/*_test.rb'
13
+ test.verbose = true
14
+ end
15
+
16
+
17
+ Rake::RDocTask.new do |rdoc|
18
+ rdoc.rdoc_dir = 'doc'
19
+ rdoc.title = "FasterXmlSimple, a libxml based replacement for XmlSimple"
20
+ rdoc.options << '--line-numbers' << '--inline-source'
21
+ rdoc.rdoc_files.include('README')
22
+ rdoc.rdoc_files.include('COPYING')
23
+ rdoc.rdoc_files.include('lib/**/*.rb')
24
+ end
25
+
26
+ namespace :dist do
27
+
28
+ spec = Gem::Specification.new do |s|
29
+ s.name = 'faster_xml_simple'
30
+ s.version = Gem::Version.new(FasterXmlSimple::Version)
31
+ s.summary = "A libxml based replacement for XmlSimple"
32
+ s.description = s.summary
33
+ s.email = 'michael@koziarski.com'
34
+ s.author = 'Michael Koziarski'
35
+ s.has_rdoc = true
36
+ s.extra_rdoc_files = %w(README COPYING)
37
+ s.homepage = 'http://fasterxs.rubyforge.org'
38
+ s.rubyforge_project = 'fasterxs'
39
+ s.files = FileList['Rakefile', 'lib/**/*.rb']
40
+ s.test_files = Dir['test/**/*']
41
+
42
+ s.add_dependency 'libxml-ruby', '>= 0.3.8.4'
43
+ s.rdoc_options = ['--title', "",
44
+ '--main', 'README',
45
+ '--line-numbers', '--inline-source']
46
+ end
47
+ Rake::GemPackageTask.new(spec) do |pkg|
48
+ pkg.need_tar_gz = true
49
+ pkg.package_files.include('{lib,test}/**/*')
50
+ pkg.package_files.include('README')
51
+ pkg.package_files.include('COPYING')
52
+ pkg.package_files.include('Rakefile')
53
+ end
54
+ end
@@ -0,0 +1,18 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'faster-xml-simple'
3
+ s.version = "0.6.3"
4
+ s.summary = "A libxml based replacement for XmlSimple"
5
+ s.description = s.summary
6
+ s.email = 'dongbin.cn@gmail.com'
7
+ s.authors = ['Michael Koziarski, Dong Bin, Lin Jian']
8
+ s.has_rdoc = true
9
+ s.extra_rdoc_files = %w(README COPYING)
10
+ s.homepage = 'http://github.com/dongbin/faster-xml-simple/tree/master'
11
+ s.files = ['COPYING', 'faster-xml-simple.gemspec', 'Rakefile', 'README', 'lib/faster_xml_simple.rb']
12
+ s.test_files = Dir['test/**/*']
13
+
14
+ s.add_dependency 'libxml-ruby', '>= 0.3.8.4'
15
+ s.rdoc_options = ['--title', "",
16
+ '--main', 'README',
17
+ '--line-numbers', '--inline-source']
18
+ end
@@ -0,0 +1,216 @@
1
+ #
2
+ # Copyright (c) 2006 Michael Koziarski
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ # this software and associated documentation files (the "Software"), to deal in the
6
+ # Software without restriction, including without limitation the rights to use,
7
+ # copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
8
+ # Software, and to permit persons to whom the Software is furnished to do so,
9
+ # subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in all
12
+ # copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18
+ # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
19
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+
21
+ require 'rubygems'
22
+ require 'xml/libxml'
23
+
24
+ class FasterXmlSimple
25
+ Version = '0.5.0'
26
+ class << self
27
+ # Take an string containing XML, and returns a hash representing that
28
+ # XML document. For example:
29
+ #
30
+ # FasterXmlSimple.xml_in("<root><something>1</something></root>")
31
+ # {"root"=>{"something"=>{"__content__"=>"1"}}}
32
+ #
33
+ # Faster XML Simple is designed to be a drop in replacement for the xml_in
34
+ # functionality of http://xml-simple.rubyforge.org
35
+ #
36
+ # The following options are supported:
37
+ #
38
+ # * <tt>contentkey</tt>: The key to use for the content of text elements,
39
+ # defaults to '\_\_content__'
40
+ # * <tt>forcearray</tt>: The list of elements which should always be returned
41
+ # as arrays. Under normal circumstances single element arrays are inlined.
42
+ # * <tt>suppressempty</tt>: The value to return for empty elements, pass +true+
43
+ # to remove empty elements entirely.
44
+ # * <tt>keeproot</tt>: By default the hash returned has a single key with the
45
+ # name of the root element. If the name of the root element isn't
46
+ # interesting to you, pass +false+.
47
+ # * <tt>forcecontent</tt>: By default a text element with no attributes, will
48
+ # be collapsed to just a string instead of a hash with a single key.
49
+ # Pass +true+ to prevent this.
50
+ #
51
+ #
52
+ def xml_in(string, options={})
53
+ new(string, options).out
54
+ end
55
+ end
56
+
57
+ def initialize(string, options) #:nodoc:
58
+ @doc = parse(string)
59
+ @options = default_options.merge options
60
+ end
61
+
62
+ def out #:nodoc:
63
+ if @options['keeproot']
64
+ {@doc.root.name => collapse(@doc.root)}
65
+ else
66
+ collapse(@doc.root)
67
+ end
68
+ end
69
+
70
+ private
71
+ def default_options
72
+ {'contentkey' => '__content__', 'forcearray' => [], 'keeproot'=> true}
73
+ end
74
+
75
+ def collapse(element)
76
+ result = hash_of_attributes(element)
77
+ if text_node? element
78
+ text = collapse_text(element)
79
+ result[content_key] = text if text =~ /\S/
80
+ elsif element.children?
81
+ element.inject(result) do |hash, child|
82
+ unless child.text?
83
+ child_result = collapse(child)
84
+ (hash[child.name] ||= []) << child_result unless child.comment?
85
+ end
86
+ hash
87
+ end
88
+ end
89
+ if result.empty?
90
+ return empty_element
91
+ end
92
+ # Compact them to ensure it complies with the user's requests
93
+ inline_single_element_arrays(result)
94
+ remove_empty_elements(result) if suppress_empty?
95
+
96
+ make_groups(result)
97
+
98
+ if content_only?(result) && !force_content?
99
+ result[content_key]
100
+ else
101
+ result
102
+ end
103
+ end
104
+
105
+ def compress_whitespace?(ele_name)
106
+ @options.has_key?('compress_whitespace') &&
107
+ @options['compress_whitespace'].include?(ele_name)
108
+ end
109
+
110
+ def compress_whitespace(text)
111
+ text.squeeze!(" \n\t")
112
+ end
113
+
114
+ def make_groups(result)
115
+ # Disintermediate grouped tags.
116
+ if @options.has_key?('grouptags')
117
+ result.each do |key, value|
118
+
119
+ next unless (value.instance_of?(Hash) && (value.size == 1))
120
+ child_key, child_value = value.to_a[0]
121
+ if @options['grouptags'][key] == child_key
122
+ result[key] = child_value
123
+ end
124
+ end
125
+ end
126
+ end
127
+
128
+ def content_only?(result)
129
+ result.keys == [content_key]
130
+ end
131
+
132
+ def content_key
133
+ @options['contentkey']
134
+ end
135
+
136
+ def force_array?(key_name)
137
+ Array(@options['forcearray']).include?(key_name)
138
+ end
139
+
140
+ def inline_single_element_arrays(result)
141
+ result.each do |key, value|
142
+ if value.size == 1 && value.is_a?(Array) && !force_array?(key)
143
+ result[key] = value.first
144
+ end
145
+ end
146
+ end
147
+
148
+ def remove_empty_elements(result)
149
+ result.each do |key, value|
150
+ if value == empty_element
151
+ result.delete key
152
+ end
153
+ end
154
+ end
155
+
156
+ def suppress_empty?
157
+ @options['suppressempty'] == true
158
+ end
159
+
160
+ def empty_element
161
+ if !@options.has_key? 'suppressempty'
162
+ {}
163
+ else
164
+ @options['suppressempty']
165
+ end
166
+ end
167
+
168
+ # removes the content if it's nothing but blanks, prevents
169
+ # the hash being polluted with lots of content like "\n\t\t\t"
170
+ def suppress_empty_content(result)
171
+ result.delete content_key if result[content_key] !~ /\S/
172
+ end
173
+
174
+ def force_content?
175
+ @options['forcecontent']
176
+ end
177
+
178
+ # a text node is one with 1 or more child nodes which are
179
+ # text nodes, and no non-text children, there's no sensible
180
+ # way to support nodes which are text and markup like:
181
+ # <p>Something <b>Bold</b> </p>
182
+ def text_node?(element)
183
+ # Support CDATA
184
+ !element.text? && element.all? {|c| c.cdata? || c.text?}
185
+ end
186
+
187
+ # takes a text node, and collapses it into a string
188
+ def collapse_text(element)
189
+ text = element.map {|c| c.content } * ''
190
+ compress_whitespace(text) if compress_whitespace?(element.name)
191
+ text
192
+ end
193
+
194
+ def hash_of_attributes(element)
195
+ result = {}
196
+ element.each_attr do |attribute|
197
+ name = attribute.name
198
+ name = [attribute.ns, attribute.name].join(':') if attribute.ns?
199
+ result[name] = attribute.value
200
+ end
201
+ result
202
+ end
203
+
204
+ def parse(string)
205
+ if string == ''
206
+ string = ' '
207
+ end
208
+ XML::Parser.string(string).parse
209
+ end
210
+ end
211
+
212
+ class XmlSimple # :nodoc:
213
+ def self.xml_in(*args)
214
+ FasterXmlSimple.xml_in *args
215
+ end
216
+ end
@@ -0,0 +1,4 @@
1
+ ---
2
+ something:
3
+ something-else:
4
+ __content__: testing
@@ -0,0 +1,3 @@
1
+ <something>
2
+ <something-else>testing</something-else>
3
+ </something>
@@ -0,0 +1,4 @@
1
+ ---
2
+ something:
3
+ something-else:
4
+ - __content__: testing
@@ -0,0 +1,6 @@
1
+ ---
2
+ something:
3
+ something-else:
4
+ __content__: testing
5
+ child_attribute: "15"
6
+ root_attribute: "12"
@@ -0,0 +1,3 @@
1
+ <something root_attribute="12">
2
+ <something-else child_attribute="15">testing</something-else>
3
+ </something>
@@ -0,0 +1,6 @@
1
+ ---
2
+ something:
3
+ something-else:
4
+ - __content__: testing
5
+ child_attribute: "15"
6
+ root_attribute: "12"
@@ -0,0 +1,6 @@
1
+ ---
2
+ something:
3
+ something-else:
4
+ __content__: "\n\
5
+ \t\ttesting\n\
6
+ \t"
@@ -0,0 +1,5 @@
1
+ <something>
2
+ <something-else>
3
+ testing
4
+ </something-else>
5
+ </something>
@@ -0,0 +1,6 @@
1
+ ---
2
+ something:
3
+ something-else:
4
+ - __content__: "\n\
5
+ \t\ttesting\n\
6
+ \t"
@@ -0,0 +1,5 @@
1
+ ---
2
+ something:
3
+ something-else:
4
+ another_child:
5
+ attribute: "4"
@@ -0,0 +1,7 @@
1
+ <something>
2
+ <something-else>
3
+ testing
4
+ <another_child attribute='4' />
5
+ testing
6
+ </something-else>
7
+ </something>
@@ -0,0 +1,5 @@
1
+ ---
2
+ something:
3
+ something-else:
4
+ - another_child:
5
+ attribute: "4"
@@ -0,0 +1,8 @@
1
+ ---
2
+ something:
3
+ something-else:
4
+ - __content__: testing
5
+ - __content__: testing
6
+ - __content__: testing
7
+ - __content__: testing
8
+ - __content__: testing
@@ -0,0 +1,7 @@
1
+ <something>
2
+ <something-else>testing</something-else>
3
+ <something-else>testing</something-else>
4
+ <something-else>testing</something-else>
5
+ <something-else>testing</something-else>
6
+ <something-else>testing</something-else>
7
+ </something>
@@ -0,0 +1,8 @@
1
+ ---
2
+ something:
3
+ something-else:
4
+ - __content__: testing
5
+ - __content__: testing
6
+ - __content__: testing
7
+ - __content__: testing
8
+ - __content__: testing
@@ -0,0 +1,43 @@
1
+ ---
2
+ ListBucketResult:
3
+ Prefix: {}
4
+
5
+ Name:
6
+ __content__: projectionist
7
+ MaxKeys:
8
+ __content__: "1000"
9
+ Contents:
10
+ - StorageClass:
11
+ __content__: STANDARD
12
+ Owner:
13
+ DisplayName:
14
+ __content__: noradio
15
+ ID:
16
+ __content__: bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1
17
+ Size:
18
+ __content__: "186870"
19
+ ETag:
20
+ __content__: "\"2ac1aa042e20ab7e1a9879b0df9f17b7\""
21
+ LastModified:
22
+ __content__: "2006-11-15T05:49:39.000Z"
23
+ Key:
24
+ __content__: 1973-plymouth-satellite-sebring.jpg
25
+ - StorageClass:
26
+ __content__: STANDARD
27
+ Owner:
28
+ DisplayName:
29
+ __content__: noradio
30
+ ID:
31
+ __content__: bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1
32
+ Size:
33
+ __content__: "43562"
34
+ ETag:
35
+ __content__: "\"4ead118ba91491f9c9697153264a1943\""
36
+ LastModified:
37
+ __content__: "2006-11-15T05:51:20.000Z"
38
+ Key:
39
+ __content__: 37-cluster.jpg
40
+ Marker: {}
41
+
42
+ IsTruncated:
43
+ __content__: "false"
@@ -0,0 +1,29 @@
1
+ <ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
2
+ <Name>projectionist</Name>
3
+ <Prefix/>
4
+ <Marker/>
5
+ <MaxKeys>1000</MaxKeys>
6
+ <IsTruncated>false</IsTruncated>
7
+ <Contents>
8
+ <Key>1973-plymouth-satellite-sebring.jpg</Key>
9
+ <LastModified>2006-11-15T05:49:39.000Z</LastModified>
10
+ <ETag>"2ac1aa042e20ab7e1a9879b0df9f17b7"</ETag>
11
+ <Size>186870</Size>
12
+ <Owner>
13
+ <ID>bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1</ID>
14
+ <DisplayName>noradio</DisplayName>
15
+ </Owner>
16
+ <StorageClass>STANDARD</StorageClass>
17
+ </Contents>
18
+ <Contents>
19
+ <Key>37-cluster.jpg</Key>
20
+ <LastModified>2006-11-15T05:51:20.000Z</LastModified>
21
+ <ETag>"4ead118ba91491f9c9697153264a1943"</ETag>
22
+ <Size>43562</Size>
23
+ <Owner>
24
+ <ID>bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1</ID>
25
+ <DisplayName>noradio</DisplayName>
26
+ </Owner>
27
+ <StorageClass>STANDARD</StorageClass>
28
+ </Contents>
29
+ </ListBucketResult>
@@ -0,0 +1,41 @@
1
+ ---
2
+ ListBucketResult:
3
+ Prefix:
4
+ Name:
5
+ __content__: projectionist
6
+ MaxKeys:
7
+ __content__: "1000"
8
+ Contents:
9
+ - StorageClass:
10
+ __content__: STANDARD
11
+ Owner:
12
+ DisplayName:
13
+ __content__: noradio
14
+ ID:
15
+ __content__: bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1
16
+ Size:
17
+ __content__: "186870"
18
+ ETag:
19
+ __content__: "\"2ac1aa042e20ab7e1a9879b0df9f17b7\""
20
+ LastModified:
21
+ __content__: "2006-11-15T05:49:39.000Z"
22
+ Key:
23
+ __content__: 1973-plymouth-satellite-sebring.jpg
24
+ - StorageClass:
25
+ __content__: STANDARD
26
+ Owner:
27
+ DisplayName:
28
+ __content__: noradio
29
+ ID:
30
+ __content__: bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1
31
+ Size:
32
+ __content__: "43562"
33
+ ETag:
34
+ __content__: "\"4ead118ba91491f9c9697153264a1943\""
35
+ LastModified:
36
+ __content__: "2006-11-15T05:51:20.000Z"
37
+ Key:
38
+ __content__: 37-cluster.jpg
39
+ Marker:
40
+ IsTruncated:
41
+ __content__: "false"
@@ -0,0 +1,23 @@
1
+ ---
2
+ AccessControlPolicy:
3
+ AccessControlList:
4
+ Grant:
5
+ - Permission:
6
+ __content__: FULL_CONTROL
7
+ Grantee:
8
+ DisplayName:
9
+ __content__: noradio
10
+ ID:
11
+ __content__: bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1
12
+ xsi:type: CanonicalUser
13
+ - Permission:
14
+ __content__: READ
15
+ Grantee:
16
+ URI:
17
+ __content__: http://acs.amazonaws.com/groups/global/AllUsers
18
+ xsi:type: Group
19
+ Owner:
20
+ DisplayName:
21
+ __content__: noradio
22
+ ID:
23
+ __content__: bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1
@@ -0,0 +1,22 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
3
+ <Owner>
4
+ <ID>bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1</ID>
5
+ <DisplayName>noradio</DisplayName>
6
+ </Owner>
7
+ <AccessControlList>
8
+ <Grant>
9
+ <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
10
+ <ID>bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1</ID>
11
+ <DisplayName>noradio</DisplayName>
12
+ </Grantee>
13
+ <Permission>FULL_CONTROL</Permission>
14
+ </Grant>
15
+ <Grant>
16
+ <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
17
+ <URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
18
+ </Grantee>
19
+ <Permission>READ</Permission>
20
+ </Grant>
21
+ </AccessControlList>
22
+ </AccessControlPolicy>
@@ -0,0 +1,22 @@
1
+ AccessControlPolicy:
2
+ Owner:
3
+ DisplayName:
4
+ __content__: noradio
5
+ ID:
6
+ __content__: bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1
7
+ AccessControlList:
8
+ Grant:
9
+ - Permission:
10
+ __content__: FULL_CONTROL
11
+ Grantee:
12
+ DisplayName:
13
+ __content__: noradio
14
+ ID:
15
+ __content__: bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1
16
+ xsi:type: CanonicalUser
17
+ - Permission:
18
+ __content__: READ
19
+ Grantee:
20
+ URI:
21
+ __content__: http://acs.amazonaws.com/groups/global/AllUsers
22
+ xsi:type: Group
@@ -0,0 +1,14 @@
1
+ ---
2
+ topic:
3
+ parent-id: {}
4
+
5
+ title: {}
6
+
7
+ approved:
8
+ type: boolean
9
+ id:
10
+ type: integer
11
+ viewed-at:
12
+ type: datetime
13
+ written-on:
14
+ type: date
@@ -0,0 +1,8 @@
1
+ <topic>
2
+ <title></title>
3
+ <id type="integer"></id>
4
+ <approved type="boolean"></approved>
5
+ <written-on type="date"></written-on>
6
+ <viewed-at type="datetime"></viewed-at>
7
+ <parent-id></parent-id>
8
+ </topic>
@@ -0,0 +1,11 @@
1
+ topic:
2
+ title:
3
+ id:
4
+ type: integer
5
+ approved:
6
+ type: boolean
7
+ parent-id:
8
+ viewed-at:
9
+ type: datetime
10
+ written-on:
11
+ type: date
@@ -0,0 +1,88 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class RegressionTest < FasterXSTest
4
+ def test_content_nil_regressions
5
+ expected = {"asdf"=>{"jklsemicolon"=>{}}}
6
+ assert_equal expected, FasterXmlSimple.xml_in("<asdf><jklsemicolon /></asdf>")
7
+ assert_equal expected, FasterXmlSimple.xml_in("<asdf><jklsemicolon /></asdf>", 'forcearray'=>['asdf'])
8
+ end
9
+
10
+ def test_s3_regression
11
+ str = File.read("test/fixtures/test-7.xml")
12
+ assert_nil FasterXmlSimple.xml_in(str)["AccessControlPolicy"]["AccessControlList"]["__content__"]
13
+ end
14
+
15
+ def test_xml_simple_transparency
16
+ assert_equal XmlSimple.xml_in("<asdf />"), FasterXmlSimple.xml_in("<asdf />")
17
+ end
18
+
19
+ def test_suppress_empty_variations
20
+ str = "<asdf><fdsa /></asdf>"
21
+
22
+ assert_equal Hash.new, FasterXmlSimple.xml_in(str)["asdf"]["fdsa"]
23
+ assert_nil FasterXmlSimple.xml_in(str, 'suppressempty'=>nil)["asdf"]["fdsa"]
24
+ assert_equal '', FasterXmlSimple.xml_in(str, 'suppressempty'=>'')["asdf"]["fdsa"]
25
+ assert !FasterXmlSimple.xml_in(str, 'suppressempty'=>true)["asdf"].has_key?("fdsa")
26
+ end
27
+
28
+ def test_empty_string_doesnt_crash
29
+ assert_raise(XML::Parser::ParseError) do
30
+ silence_stderr do
31
+ FasterXmlSimple.xml_in('')
32
+ end
33
+ end
34
+ end
35
+
36
+ def test_keeproot_false
37
+ str = "<asdf><fdsa>1</fdsa></asdf>"
38
+ expected = {"fdsa"=>"1"}
39
+ assert_equal expected, FasterXmlSimple.xml_in(str, 'keeproot'=>false)
40
+ end
41
+
42
+ def test_keeproot_false_with_force_content
43
+ str = "<asdf><fdsa>1</fdsa></asdf>"
44
+ expected = {"fdsa"=>{"__content__"=>"1"}}
45
+ assert_equal expected, FasterXmlSimple.xml_in(str, 'keeproot'=>false, 'forcecontent'=>true)
46
+ end
47
+
48
+ def test_group_tag
49
+ str = "<a>
50
+ <c>
51
+ <b>1</b>
52
+ <b>2</b>
53
+ </c>
54
+ </a>"
55
+ expected = { "a" => { 'c' => ["1", "2"] }}
56
+ assert_equal expected, FasterXmlSimple.xml_in(str, 'grouptags' => { 'c' => 'b'})
57
+
58
+ end
59
+
60
+ def test_compress_whitespace
61
+ str = "<a><b> a b </b></a>"
62
+ expected = { "a" => { 'b' => " a b "}}
63
+ assert_equal expected, FasterXmlSimple.xml_in(str, 'compress_whitespace' => ['b'])
64
+
65
+ end
66
+
67
+
68
+ def test_cdata
69
+ str = "<a> <b><![CDATA[ a ]]></b> </a>"
70
+ expected = { "a" => { "b" => " a "}}
71
+ assert_equal expected, FasterXmlSimple.xml_in(str)
72
+
73
+ end
74
+
75
+ def test_remove_comment
76
+ str = %Q(<r>
77
+ <a>a</a>
78
+ <!--<b>b</b>-->
79
+ <titles>
80
+ <title>1</title>
81
+ <title>2</title>
82
+ <!--<title>3</title>-->
83
+ </titles>
84
+ </r>)
85
+ expected = {"r" => {"a" => "a", "titles"=>{"title"=>["1", "2"]}} }
86
+ assert_equal expected, FasterXmlSimple.xml_in(str)
87
+ end
88
+ end
@@ -0,0 +1,17 @@
1
+
2
+ require 'test/unit'
3
+ require 'faster_xml_simple'
4
+
5
+ class FasterXSTest < Test::Unit::TestCase
6
+ def default_test
7
+ end
8
+
9
+ def silence_stderr
10
+ str = STDERR.dup
11
+ STDERR.reopen("/dev/null")
12
+ STDERR.sync=true
13
+ yield
14
+ ensure
15
+ STDERR.reopen(str)
16
+ end
17
+ end
@@ -0,0 +1,46 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+ require 'yaml'
3
+
4
+ class XmlSimpleComparisonTest < FasterXSTest
5
+
6
+ # Define test methods
7
+
8
+ Dir["test/fixtures/test-*.xml"].each do |file_name|
9
+ xml_file_name = file_name
10
+ method_name = File.basename(file_name, ".xml").gsub('-', '_')
11
+ yml_file_name = file_name.gsub('xml', 'yml')
12
+ rails_yml_file_name = file_name.gsub('xml', 'rails.yml')
13
+ class_eval <<-EOV, __FILE__, __LINE__
14
+ def #{method_name}
15
+ assert_equal YAML.load(File.read('#{yml_file_name}')),
16
+ FasterXmlSimple.xml_in(File.read('#{xml_file_name}'), default_options )
17
+ end
18
+
19
+ def #{method_name}_rails
20
+ assert_equal YAML.load(File.read('#{rails_yml_file_name}')),
21
+ FasterXmlSimple.xml_in(File.read('#{xml_file_name}'), rails_options)
22
+ end
23
+ EOV
24
+ end
25
+
26
+ def default_options
27
+ {
28
+ 'keeproot' => true,
29
+ 'contentkey' => '__content__',
30
+ 'forcecontent' => true,
31
+ 'suppressempty' => nil,
32
+ 'forcearray' => ['something-else']
33
+ }
34
+ end
35
+
36
+ def rails_options
37
+ {
38
+ 'forcearray' => false,
39
+ 'forcecontent' => true,
40
+ 'keeproot' => true,
41
+ 'contentkey' => '__content__'
42
+ }
43
+ end
44
+
45
+
46
+ end
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dongbin-faster-xml-simple
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.6.3
5
+ platform: ruby
6
+ authors:
7
+ - Michael Koziarski, Dong Bin, Lin Jian
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-06-13 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: libxml-ruby
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.3.8.4
23
+ version:
24
+ description: A libxml based replacement for XmlSimple
25
+ email: dongbin.cn@gmail.com
26
+ executables: []
27
+
28
+ extensions: []
29
+
30
+ extra_rdoc_files:
31
+ - README
32
+ - COPYING
33
+ files:
34
+ - COPYING
35
+ - faster-xml-simple.gemspec
36
+ - Rakefile
37
+ - README
38
+ - lib/faster_xml_simple.rb
39
+ has_rdoc: true
40
+ homepage: http://github.com/dongbin/faster-xml-simple/tree/master
41
+ post_install_message:
42
+ rdoc_options:
43
+ - --title
44
+ - ""
45
+ - --main
46
+ - README
47
+ - --line-numbers
48
+ - --inline-source
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ version:
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ requirements: []
64
+
65
+ rubyforge_project:
66
+ rubygems_version: 1.2.0
67
+ signing_key:
68
+ specification_version: 2
69
+ summary: A libxml based replacement for XmlSimple
70
+ test_files:
71
+ - test/xml_simple_comparison_test.rb
72
+ - test/fixtures
73
+ - test/fixtures/test-1.rails.yml
74
+ - test/fixtures/test-8.rails.yml
75
+ - test/fixtures/test-4.rails.yml
76
+ - test/fixtures/test-1.xml
77
+ - test/fixtures/test-1.yml
78
+ - test/fixtures/test-2.xml
79
+ - test/fixtures/test-2.yml
80
+ - test/fixtures/test-3.xml
81
+ - test/fixtures/test-3.yml
82
+ - test/fixtures/test-4.xml
83
+ - test/fixtures/test-4.yml
84
+ - test/fixtures/test-5.xml
85
+ - test/fixtures/test-5.yml
86
+ - test/fixtures/test-6.xml
87
+ - test/fixtures/test-6.yml
88
+ - test/fixtures/test-7.xml
89
+ - test/fixtures/test-7.yml
90
+ - test/fixtures/test-8.xml
91
+ - test/fixtures/test-8.yml
92
+ - test/fixtures/test-7.rails.yml
93
+ - test/fixtures/test-3.rails.yml
94
+ - test/fixtures/test-6.rails.yml
95
+ - test/fixtures/test-2.rails.yml
96
+ - test/fixtures/test-5.rails.yml
97
+ - test/regression_test.rb
98
+ - test/test_helper.rb