libxml-ruby 2.2.1 → 2.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/HISTORY CHANGED
@@ -1,5 +1,31 @@
1
1
  = Release History
2
2
 
3
+ == 2.2.2 / 2011-08-13 Charlie Savage
4
+
5
+ * ++API CHANGE+++
6
+
7
+ Reader#relax_ng_validate now takes a RelaxNG object. This is
8
+ what the documentation has always said it takes, but it previously
9
+ took a string. In addition, it now returns true or false instead of 0 or -1.
10
+
11
+ Reader#schema_validate now takes a Schema object. This is
12
+ what the documentation has always said it takes, but it previously
13
+ took a string. In addition, it now returns true or false instead of 0 or -1.
14
+
15
+ Fixes GitHub issue #30.
16
+
17
+ * Added Parser::Context#close and HTMLParser::Context#close methods that
18
+ allow the underlying io stream (file, string, etc) to be closed. Once a
19
+ parser is done parsing its data, it now calls one of these methods.
20
+ This means that if you parse thousands of files at the same time,
21
+ without running Ruby's garbage colllector, you won't get a too
22
+ many files open error. Fixes GitHub issue #29.
23
+
24
+ * Fixed bug where Node#inner_xml caused an error when it had no child nodes.
25
+ Fixes GitHub issues #31
26
+
27
+ * Don't require 'rake' in the gemspec to avoid annoying Bunlder bugs
28
+
3
29
  == 2.2.1 / 2011-08-13 Charlie Savage
4
30
 
5
31
  * Packaging fix - include the custom .def file in the gem.
data/Rakefile CHANGED
@@ -5,7 +5,6 @@ require "rake/extensiontask"
5
5
  require "rake/testtask"
6
6
  require "rubygems/package_task"
7
7
  require "rdoc/task"
8
- require "grancher/task"
9
8
  require "yaml"
10
9
 
11
10
  GEM_NAME = "libxml-ruby"
@@ -76,17 +75,5 @@ Rake::TestTask.new do |t|
76
75
  t.verbose = true
77
76
  end
78
77
 
79
- # Publish Website to Github
80
- Grancher::Task.new do |g|
81
- # push gh-pages
82
- g.branch = 'gh-pages'
83
- # to origin
84
- g.push_to = 'origin'
85
- # copy the website directory
86
- g.directory 'web'
87
- # and the rdoc directory
88
- g.directory 'doc/libxml-ruby/rdoc', 'rdoc'
89
- end
90
-
91
78
  desc "Build docs, and publish the website"
92
79
  task :publish_with_docs => [:rdoc, :publish]
@@ -72,6 +72,8 @@ static VALUE rxml_html_parser_parse(VALUE self)
72
72
  rxml_raise(&ctxt->lastError);
73
73
  }
74
74
 
75
+ rb_funcall(context, rb_intern("close"), 0);
76
+
75
77
  return rxml_document_wrap(ctxt->myDoc);
76
78
  }
77
79
 
@@ -249,6 +249,27 @@ static VALUE rxml_html_parser_context_string(VALUE klass, VALUE string)
249
249
  return rxml_html_parser_context_wrap(ctxt);
250
250
  }
251
251
 
252
+ /*
253
+ * call-seq:
254
+ * context.close -> nil
255
+ *
256
+ * Closes the underlying input streams. This is useful when parsing a large amount of
257
+ * files and you want to close the files without relying on Ruby's garbage collector
258
+ * to run.
259
+ */
260
+ static VALUE rxml_html_parser_context_close(VALUE self)
261
+ {
262
+ htmlParserCtxtPtr ctxt;
263
+ xmlParserInputPtr xinput;
264
+ Data_Get_Struct(self, htmlParserCtxt, ctxt);
265
+
266
+ while ((xinput = inputPop(ctxt)) != NULL)
267
+ {
268
+ xmlFreeInputStream(xinput);
269
+ }
270
+ return Qnil;
271
+ }
272
+
252
273
  /*
253
274
  * call-seq:
254
275
  * context.disable_cdata = (true|false)
@@ -311,6 +332,7 @@ void rxml_init_html_parser_context(void)
311
332
  rb_define_singleton_method(cXMLHtmlParserContext, "file", rxml_html_parser_context_file, 1);
312
333
  rb_define_singleton_method(cXMLHtmlParserContext, "io", rxml_html_parser_context_io, 1);
313
334
  rb_define_singleton_method(cXMLHtmlParserContext, "string", rxml_html_parser_context_string, 1);
335
+ rb_define_method(cXMLHtmlParserContext, "close", rxml_html_parser_context_close, 0);
314
336
  rb_define_method(cXMLHtmlParserContext, "disable_cdata=", rxml_html_parser_context_disable_cdata_set, 1);
315
337
  rb_define_method(cXMLHtmlParserContext, "options=", rxml_html_parser_context_options_set, 1);
316
338
  }
@@ -74,6 +74,8 @@ static VALUE rxml_parser_parse(VALUE self)
74
74
  rxml_raise(&ctxt->lastError);
75
75
  }
76
76
 
77
+ rb_funcall(context, rb_intern("close"), 0);
78
+
77
79
  return rxml_document_wrap(ctxt->myDoc);
78
80
  }
79
81
 
@@ -214,6 +214,26 @@ static VALUE rxml_parser_context_base_uri_set(VALUE self, VALUE url)
214
214
  return self;
215
215
  }
216
216
 
217
+ /*
218
+ * call-seq:
219
+ * context.close -> nil
220
+ *
221
+ * Closes the underlying input streams. This is useful when parsing a large amount of
222
+ * files and you want to close the files without relying on Ruby's garbage collector
223
+ * to run.
224
+ */
225
+ static VALUE rxml_parser_context_close(VALUE self)
226
+ {
227
+ xmlParserCtxtPtr ctxt;
228
+ xmlParserInputPtr xinput;
229
+ Data_Get_Struct(self, xmlParserCtxt, ctxt);
230
+
231
+ while ((xinput = inputPop(ctxt)) != NULL)
232
+ {
233
+ xmlFreeInputStream(xinput);
234
+ }
235
+ return Qnil;
236
+ }
217
237
 
218
238
  /*
219
239
  * call-seq:
@@ -937,6 +957,7 @@ void rxml_init_parser_context(void)
937
957
 
938
958
  rb_define_method(cXMLParserContext, "base_uri", rxml_parser_context_base_uri_get, 0);
939
959
  rb_define_method(cXMLParserContext, "base_uri=", rxml_parser_context_base_uri_set, 1);
960
+ rb_define_method(cXMLParserContext, "close", rxml_parser_context_close, 0);
940
961
  rb_define_method(cXMLParserContext, "data_directory", rxml_parser_context_data_directory_get, 0);
941
962
  rb_define_method(cXMLParserContext, "depth", rxml_parser_context_depth_get, 0);
942
963
  rb_define_method(cXMLParserContext, "disable_cdata?", rxml_parser_context_disable_cdata_q, 0);
@@ -562,41 +562,48 @@ static VALUE rxml_reader_read_string(VALUE self)
562
562
 
563
563
  /*
564
564
  * call-seq:
565
- * reader.relax_ng_validate(rng) -> code
565
+ * reader.relax_ng_validate(rng) -> boolean
566
566
  *
567
567
  * Use RelaxNG to validate the document as it is processed. Activation is only
568
568
  * possible before the first read. If +rng+ is nil, the RelaxNG validation is
569
569
  * desactivated.
570
570
  *
571
- * Return 0 in case the RelaxNG validation could be (des)activated and -1 in
571
+ * Return true in case the RelaxNG validation could be (des)activated and false in
572
572
  * case of error.
573
573
  */
574
574
  static VALUE rxml_reader_relax_ng_validate(VALUE self, VALUE rng)
575
575
  {
576
- char *xrng = NIL_P(rng) ? NULL : StringValueCStr(rng);
577
576
  xmlTextReaderPtr xreader = rxml_text_reader_get(self);
578
- return INT2FIX(xmlTextReaderRelaxNGValidate(xreader, xrng));
577
+ xmlRelaxNGPtr xrelax;
578
+ int status;
579
+ Data_Get_Struct(rng, xmlRelaxNG, xrelax);
580
+
581
+ status = xmlTextReaderRelaxNGSetSchema(xreader, xrelax);
582
+ return (status == 0 ? Qtrue : Qfalse);
579
583
  }
580
584
 
581
585
  #if LIBXML_VERSION >= 20620
582
586
  /*
583
587
  * call-seq:
584
- * reader.schema_validate(schema) -> code
588
+ * reader.schema_validate(schema) -> boolean
585
589
  *
586
590
  * Use W3C XSD schema to validate the document as it is processed. Activation
587
591
  * is only possible before the first read. If +schema+ is nil, then XML Schema
588
- * validation is desactivated.
592
+ * validation is deactivated.
589
593
  *
590
- * Return 0 in case the schemas validation could be (de)activated and -1 in
591
- * case of error.
594
+ * Return false if if the schema's validation could be (de)activated and true
595
+ * otherwise.
592
596
  */
593
597
  static VALUE
594
598
  rxml_reader_schema_validate(VALUE self, VALUE xsd)
595
599
  {
596
- char *xxsd = NIL_P(xsd) ? NULL : StringValueCStr(xsd);
597
600
  xmlTextReaderPtr xreader = rxml_text_reader_get(self);
598
- int status = xmlTextReaderSchemaValidate(xreader, xxsd);
599
- return INT2FIX(status);
601
+ xmlSchemaPtr xschema;
602
+ int status;
603
+
604
+ Data_Get_Struct(xsd, xmlSchema, xschema);
605
+ status = xmlTextReaderSetSchema(xreader, xschema);
606
+ return (status == 0 ? Qtrue : Qfalse);
600
607
  }
601
608
  #endif
602
609
 
@@ -4,6 +4,9 @@
4
4
  #ifndef __RXML_READER__
5
5
  #define __RXML_READER__
6
6
 
7
+ #include <libxml/xmlreader.h>
8
+ #include <libxml/xmlschemas.h>
9
+
7
10
  extern VALUE cXMLReader;
8
11
 
9
12
  void rxml_init_reader(void);
@@ -1,9 +1,9 @@
1
1
  /* Don't nuke this block! It is used for automatically updating the
2
2
  * versions below. VERSION = string formatting, VERNUM = numbered
3
3
  * version for inline testing: increment both or none at all.*/
4
- #define RUBY_LIBXML_VERSION "2.2.1"
5
- #define RUBY_LIBXML_VERNUM 221
4
+ #define RUBY_LIBXML_VERSION "2.2.2"
5
+ #define RUBY_LIBXML_VERNUM 222
6
6
  #define RUBY_LIBXML_VER_MAJ 2
7
7
  #define RUBY_LIBXML_VER_MIN 2
8
- #define RUBY_LIBXML_VER_MIC 1
8
+ #define RUBY_LIBXML_VER_MIC 2
9
9
  #define RUBY_LIBXML_VER_PATCH 0
@@ -32,7 +32,7 @@ module LibXML
32
32
  io << xml
33
33
  end
34
34
 
35
- io.string
35
+ io ? io.string : nil
36
36
  end
37
37
 
38
38
  # :call-seq:
@@ -1,29 +1,8 @@
1
1
  # encoding: utf-8
2
- require 'rake'
3
2
 
4
3
  # Determine the current version of the software
5
4
  version = File.read('ext/libxml/ruby_xml_version.h').match(/\s*RUBY_LIBXML_VERSION\s*['"](\d.+)['"]/)[1]
6
5
 
7
- # ------- Default Package ----------
8
- FILES = FileList[
9
- 'HISTORY',
10
- 'LICENSE',
11
- 'libxml-ruby.gemspec',
12
- 'MANIFEST',
13
- 'Rakefile',
14
- 'README.rdoc',
15
- 'setup.rb',
16
- 'ext/libxml/*.def',
17
- 'ext/libxml/*.h',
18
- 'ext/libxml/*.c',
19
- 'ext/libxml/*.rb',
20
- 'ext/vc/*.sln',
21
- 'ext/vc/*.vcprojx',
22
- 'lib/**/*.rb',
23
- 'script/**/*',
24
- 'test/**/*'
25
- ]
26
-
27
6
  Gem::Specification.new do |spec|
28
7
  spec.name = 'libxml-ruby'
29
8
  spec.version = version
@@ -41,9 +20,23 @@ Gem::Specification.new do |spec|
41
20
  spec.platform = Gem::Platform::RUBY
42
21
  spec.bindir = "bin"
43
22
  spec.extensions = ["ext/libxml/extconf.rb"]
44
- spec.files = FILES.to_a
23
+ spec.files = Dir.glob(['HISTORY',
24
+ 'LICENSE',
25
+ 'libxml-ruby.gemspec',
26
+ 'MANIFEST',
27
+ 'Rakefile',
28
+ 'README.rdoc',
29
+ 'setup.rb',
30
+ 'ext/libxml/*.def',
31
+ 'ext/libxml/*.h',
32
+ 'ext/libxml/*.c',
33
+ 'ext/libxml/*.rb',
34
+ 'ext/vc/*.sln',
35
+ 'ext/vc/*.vcprojx',
36
+ 'lib/**/*.rb',
37
+ 'script/**/*',
38
+ 'test/**/*'])
45
39
  spec.test_files = Dir.glob("test/tc_*.rb")
46
-
47
40
  spec.required_ruby_version = '>= 1.8.6'
48
41
  spec.date = DateTime.now
49
42
  end
@@ -143,4 +143,12 @@
143
143
  environment.
144
144
  </description>
145
145
  </book>
146
+ <book id="bk113">
147
+ <author>Test Mike</author>
148
+ <title>Test Data with empty nodes</title>
149
+ <genre/>
150
+ <price/>
151
+ <publish_date/>
152
+ <description/>
153
+ </book>
146
154
  </catalog>
@@ -131,7 +131,7 @@ class TestError < Test::Unit::TestCase
131
131
  parser.parse
132
132
  end
133
133
 
134
- assert_equal("Fatal error: Document is empty at :1.", error.to_s)
134
+ assert_equal(" LibXML::XML::Error.", error.to_s)
135
135
  end
136
136
 
137
137
  def test_libxml_parser_empty_string
@@ -144,4 +144,10 @@ class HTMLParserTest < Test::Unit::TestCase
144
144
  doc = parser.parse
145
145
  assert_equal("<p>#{html}</p>", doc.root.to_s)
146
146
  end
147
+
148
+ def test_open_many_files
149
+ 1000.times do
150
+ doc = XML::HTMLParser.file('model/ruby-lang.html').parse
151
+ end
152
+ end
147
153
  end
@@ -256,6 +256,11 @@ class TestParser < Test::Unit::TestCase
256
256
  XML::Error.reset_handler {|error|}
257
257
  end
258
258
 
259
+ def test_open_many_files
260
+ 1000.times do
261
+ doc = XML::Parser.file('model/atom.xml').parse
262
+ end
263
+ end
259
264
 
260
265
  # ----- Errors ------
261
266
  def test_error
@@ -18,36 +18,73 @@ class TestSchema < Test::Unit::TestCase
18
18
  XML::Schema.document(document)
19
19
  end
20
20
 
21
- def test_from_doc
22
- assert_instance_of(XML::Schema, schema)
23
- end
24
-
25
- def test_valid
26
- assert(@doc.validate_schema(schema))
27
- end
28
-
29
- def test_invalid
30
- new_node = XML::Node.new('invalid', 'this will mess up validation')
31
- @doc.root << new_node
32
-
33
- error = assert_raise(XML::Error) do
34
- @doc.validate_schema(schema)
35
- end
36
-
21
+ def check_error(error)
37
22
  assert_not_nil(error)
38
- assert_kind_of(XML::Error, error)
39
23
  assert(error.message.match(/Error: Element 'invalid': This element is not expected. Expected is \( item \)/))
24
+ assert_kind_of(XML::Error, error)
40
25
  assert_equal(XML::Error::SCHEMASV, error.domain)
41
26
  assert_equal(XML::Error::SCHEMAV_ELEMENT_CONTENT, error.code)
42
27
  assert_equal(XML::Error::ERROR, error.level)
43
- assert(error.file.match(/shiporder.xml/))
28
+ assert(error.file.match(/shiporder.xml/)) if error.file
44
29
  assert_nil(error.line)
45
30
  assert_nil(error.str1)
46
31
  assert_nil(error.str2)
47
32
  assert_nil(error.str3)
48
33
  assert_equal(0, error.int1)
49
34
  assert_equal(0, error.int2)
35
+ end
36
+
37
+ def test_load_from_doc
38
+ assert_instance_of(XML::Schema, schema)
39
+ end
40
+
41
+ def test_doc_valid
42
+ assert(@doc.validate_schema(schema))
43
+ end
44
+
45
+ def test_doc_invalid
46
+ new_node = XML::Node.new('invalid', 'this will mess up validation')
47
+ @doc.root << new_node
48
+
49
+ error = assert_raise(XML::Error) do
50
+ @doc.validate_schema(schema)
51
+ end
52
+
53
+ check_error(error)
50
54
  assert_not_nil(error.node)
51
55
  assert_equal('invalid', error.node.name)
52
56
  end
53
- end
57
+
58
+ def test_reader_valid
59
+ reader = XML::Reader.string(@doc.to_s)
60
+ assert(reader.schema_validate(schema))
61
+
62
+ while reader.read
63
+ end
64
+ end
65
+
66
+ def test_reader_invalid
67
+ # Set error handler
68
+ errors = Array.new
69
+ XML::Error.set_handler do |error|
70
+ errors << error
71
+ end
72
+
73
+ new_node = XML::Node.new('invalid', 'this will mess up validation')
74
+ @doc.root << new_node
75
+ reader = XML::Reader.string(@doc.to_s)
76
+
77
+ # Set a schema
78
+ assert(reader.schema_validate(schema))
79
+
80
+ while reader.read
81
+ end
82
+
83
+ assert_equal(1, errors.length)
84
+
85
+ error = errors.first
86
+ check_error(error)
87
+ ensure
88
+ XML::Error.set_handler(&LibXML::XML::Error::VERBOSE_HANDLER)
89
+ end
90
+ end
@@ -4,8 +4,8 @@ require './test_helper'
4
4
  require 'test/unit'
5
5
 
6
6
  class TestTranversal < Test::Unit::TestCase
7
- ROOT_NODES_LENGTH = 25
8
- ROOT_ELEMENTS_LENGTH = 12
7
+ ROOT_NODES_LENGTH = 27
8
+ ROOT_ELEMENTS_LENGTH = 13
9
9
 
10
10
  def setup
11
11
  filename = File.join(File.dirname(__FILE__), 'model/books.xml')
@@ -30,7 +30,18 @@ class TestTranversal < Test::Unit::TestCase
30
30
 
31
31
  assert_equal(ROOT_NODES_LENGTH, nodes.length)
32
32
  end
33
-
33
+
34
+ def test_no_children
35
+ # Get a node with no children
36
+ node = @doc.find_first('/catalog/book[@id="bk113"]/price')
37
+ assert_equal(0, node.children.length)
38
+ end
39
+
40
+ def test_no_children_inner_xml
41
+ # Get a node with no children
42
+ node = @doc.find_first('/catalog/book[@id="bk113"]/price')
43
+ assert_nil(node.inner_xml)
44
+ end
34
45
  def test_each
35
46
  # Includes text nodes and such
36
47
  nodes = @doc.root.inject([]) do |arr, node|
@@ -131,92 +142,12 @@ class TestTranversal < Test::Unit::TestCase
131
142
 
132
143
  assert_equal(@doc.root.children, next_nodes)
133
144
  end
134
-
135
- # node = @doc.find_first('book')
136
- # node.children.each do |node|
137
- # puts 1
138
- #end
139
- # @doc.root.children do |node|
140
- # if node.node_type == XML::Node::ELEMENT_NODE
141
- # puts node.name
142
- #end
143
- #end
144
- #assert_equal(12,nodes.length)
145
- #end
146
-
147
- #def test_doc_class
148
- #assert_instance_of(XML::Document, @doc)
149
- #end
150
-
151
- #def test_root_class
152
- #assert_instance_of(XML::Node, @doc.root)
153
- #end
154
-
155
- #def test_node_class
156
- #for n in nodes
157
- #assert_instance_of(XML::Node, n)
158
- #end
159
- #end
160
-
161
- #def test_find_class
162
- #set = @doc.find('/ruby_array/fixnum')
163
- #assert_instance_of(XML::XPath::Object, set)
164
- #end
165
145
 
166
- #def test_node_child_get
167
- #assert_instance_of(TrueClass, @doc.root.child?)
168
- #assert_instance_of(XML::Node, @doc.root.child)
169
- #assert_equal('fixnum', @doc.root.child.name)
170
- #end
171
-
172
- #def test_node_doc
173
- #for n in nodes
174
- #assert_instance_of(XML::Document, n.doc) if n.document?
175
- #end
176
- #end
177
-
178
- #def test_node_type_name
179
- #assert_equal('element', nodes[0].node_type_name)
180
- #assert_equal('element', nodes[1].node_type_name)
181
- #end
182
-
183
- #def test_node_find
184
- #set = @doc.root.find('./fixnum').set
185
- #assert_instance_of(XML::Node::Set, set)
186
- #for node in set
187
- #assert_instance_of(XML::Node, node)
188
- #end
189
- #end
190
-
191
- #def test_equality
192
- #node_a = @doc.find('/ruby_array/fixnum').first
193
- #node_b = @doc.root.child
194
- #assert(node_a == node_b)
195
- #assert(node_a.eql?(node_b))
196
- #assert(node_a.equal?(node_b))
197
-
198
- #xp2 = XML::Parser.new()
199
- #xp2.string = '<ruby_array uga="booga" foo="bar"><fixnum>one</fixnum><fixnum>two</fixnum></ruby_array>'
200
- #doc2 = xp2.parse
201
-
202
- #node_a2 = doc2.find('/ruby_array/fixnum').first
203
-
204
- #assert(node_a.to_s == node_a2.to_s)
205
- #assert(node_a == node_a2)
206
- #assert(node_a.eql?(node_a2))
207
- #assert(!node_a.equal?(node_a2))
208
- #end
209
-
210
- #def test_content()
211
- #assert_equal('onetwo', @doc.root.content)
212
-
213
- #first = @doc.root.child
214
- #assert_equal('one', first.content)
215
- #assert_equal('two', first.next.content)
216
- #end
146
+ def test_doc_class
147
+ assert_instance_of(XML::Document, @doc)
148
+ end
217
149
 
218
- #def test_base
219
- #doc = XML::Parser.string('<person />').parse
220
- #assert_nil(doc.root.base)
221
- #end
150
+ def test_root_class
151
+ assert_instance_of(XML::Node, @doc.root)
152
+ end
222
153
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: libxml-ruby
3
3
  version: !ruby/object:Gem::Version
4
- hash: 5
4
+ hash: 3
5
5
  prerelease:
6
6
  segments:
7
7
  - 2
8
8
  - 2
9
- - 1
10
- version: 2.2.1
9
+ - 2
10
+ version: 2.2.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ross Bamform
@@ -20,7 +20,7 @@ autorequire:
20
20
  bindir: bin
21
21
  cert_chain: []
22
22
 
23
- date: 2011-08-14 00:00:00 Z
23
+ date: 2011-08-29 00:00:00 Z
24
24
  dependencies: []
25
25
 
26
26
  description: " The Libxml-Ruby project provides Ruby language bindings for the GNOME\n Libxml2 XML toolkit. It is free software, released under the MIT License.\n Libxml-ruby's primary advantage over REXML is performance - if speed\n is your need, these are good libraries to consider, as demonstrated\n by the informal benchmark below.\n"
@@ -227,7 +227,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
227
227
  requirements: []
228
228
 
229
229
  rubyforge_project:
230
- rubygems_version: 1.8.6
230
+ rubygems_version: 1.7.2
231
231
  signing_key:
232
232
  specification_version: 3
233
233
  summary: Ruby Bindings for LibXML2