nokogiri 1.3.1-x86-mswin32 → 1.3.2-x86-mswin32

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of nokogiri might be problematic. Click here for more details.

Files changed (64) hide show
  1. data/CHANGELOG.ja.rdoc +25 -0
  2. data/CHANGELOG.rdoc +23 -0
  3. data/Manifest.txt +5 -0
  4. data/README.ja.rdoc +5 -5
  5. data/README.rdoc +3 -3
  6. data/Rakefile +25 -21
  7. data/ext/nokogiri/extconf.rb +54 -12
  8. data/ext/nokogiri/xml_document.c +4 -1
  9. data/ext/nokogiri/xml_document.h +2 -0
  10. data/ext/nokogiri/xml_dtd.c +29 -0
  11. data/ext/nokogiri/xml_node.c +9 -1
  12. data/ext/nokogiri/xml_node_set.c +5 -1
  13. data/ext/nokogiri/xml_relax_ng.c +50 -3
  14. data/ext/nokogiri/xml_sax_parser.c +84 -77
  15. data/ext/nokogiri/xml_schema.c +52 -3
  16. data/ext/nokogiri/xml_syntax_error.c +7 -0
  17. data/ext/nokogiri/xml_syntax_error.h +1 -0
  18. data/lib/nokogiri.rb +2 -2
  19. data/lib/nokogiri/1.8/nokogiri.so +0 -0
  20. data/lib/nokogiri/1.9/nokogiri.so +0 -0
  21. data/lib/nokogiri/css/parser.rb +2 -2
  22. data/lib/nokogiri/ffi/io_callbacks.rb +20 -12
  23. data/lib/nokogiri/ffi/libxml.rb +8 -0
  24. data/lib/nokogiri/ffi/xml/document.rb +1 -1
  25. data/lib/nokogiri/ffi/xml/dtd.rb +22 -6
  26. data/lib/nokogiri/ffi/xml/namespace.rb +9 -7
  27. data/lib/nokogiri/ffi/xml/node.rb +4 -0
  28. data/lib/nokogiri/ffi/xml/node_set.rb +4 -1
  29. data/lib/nokogiri/ffi/xml/relax_ng.rb +35 -3
  30. data/lib/nokogiri/ffi/xml/sax/parser.rb +20 -19
  31. data/lib/nokogiri/ffi/xml/schema.rb +41 -4
  32. data/lib/nokogiri/html.rb +2 -2
  33. data/lib/nokogiri/html/document.rb +3 -3
  34. data/lib/nokogiri/version.rb +2 -2
  35. data/lib/nokogiri/xml.rb +3 -3
  36. data/lib/nokogiri/xml/document.rb +14 -4
  37. data/lib/nokogiri/xml/fragment_handler.rb +8 -0
  38. data/lib/nokogiri/xml/node.rb +1 -104
  39. data/lib/nokogiri/xml/node_set.rb +46 -6
  40. data/lib/nokogiri/xml/parse_options.rb +7 -2
  41. data/lib/nokogiri/xml/relax_ng.rb +2 -2
  42. data/lib/nokogiri/xml/sax.rb +1 -0
  43. data/lib/nokogiri/xml/sax/document.rb +4 -4
  44. data/lib/nokogiri/xml/sax/legacy_handlers.rb +65 -0
  45. data/lib/nokogiri/xml/sax/parser.rb +7 -0
  46. data/lib/nokogiri/xml/sax/push_parser.rb +3 -0
  47. data/lib/nokogiri/xml/schema.rb +1 -5
  48. data/lib/xsd/xmlparser/nokogiri.rb +14 -7
  49. data/tasks/test.rb +1 -62
  50. data/test/files/bar/bar.xsd +4 -0
  51. data/test/files/foo/foo.xsd +4 -0
  52. data/test/files/snuggles.xml +3 -0
  53. data/test/files/valid_bar.xml +2 -0
  54. data/test/helper.rb +9 -8
  55. data/test/html/test_document_fragment.rb +14 -0
  56. data/test/test_reader.rb +10 -10
  57. data/test/xml/sax/test_parser.rb +77 -0
  58. data/test/xml/sax/test_push_parser.rb +11 -7
  59. data/test/xml/test_document.rb +25 -0
  60. data/test/xml/test_dtd.rb +6 -1
  61. data/test/xml/test_node.rb +7 -0
  62. data/test/xml/test_node_set.rb +19 -0
  63. data/test/xml/test_schema.rb +24 -0
  64. metadata +10 -5
data/CHANGELOG.ja.rdoc CHANGED
@@ -1,3 +1,28 @@
1
+ === 1.3.2 / 2009年6月22日
2
+
3
+ * 新しい機能
4
+
5
+ * Nokogiri::XML::DTD#validate はドキュメントを検証できるようになった
6
+
7
+ * バグの修正
8
+
9
+ * Nokogiri::XML::NodeSet#search はトップレベルのノードを検索するようになった
10
+ GH #73
11
+ * Nokogiri::XML::Documentからメソッドに関係する名前空間を取り除いた
12
+ * 同じ名前空間を2回目に入れた時に起るセグフォールトを修正した
13
+ * Snow Leopard で Nokogiri は動くようになった GH #79
14
+ * メーリングリストはGoogle Groupsの以下のアドレスに移動した
15
+ http://groups.google.com/group/nokogiri-talk
16
+ * HTML フラグメントはコメントとCDATAを正確に扱うようになった
17
+ * Nokogiri::XML::Document#cloneはdupのエイリアスと同様の働きをする
18
+
19
+ * 廃棄予定
20
+
21
+ * Nokogiri::XML::SAX::Document#start_element_nsは廃棄予定なので
22
+ Nokogiri::XML::SAX::Document#start_element_namespaceを代わりに使用して下さい
23
+ * Nokogiri::XML::SAX::Document#end_element_nsは廃棄予定なので
24
+ Nokogiri::XML::SAX::Document#end_element_namespaceを代わりに使用して下さい
25
+
1
26
  === 1.3.1 / 2009年6月7日
2
27
 
3
28
  * バグの修正
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,26 @@
1
+ === 1.3.2 / 2009-06-22
2
+
3
+ * New Features
4
+
5
+ * Nokogiri::XML::DTD#validate will validate your document
6
+
7
+ * Bugfixes
8
+
9
+ * Nokogiri::XML::NodeSet#search will search top level nodes. GH #73
10
+ * Removed namespace related methods from Nokogiri::XML::Document
11
+ * Fixed a segfault when a namespace was added twice
12
+ * Made nokogiri work with Snow Leopard GH #79
13
+ * Mailing list has moved to: http://groups.google.com/group/nokogiri-talk
14
+ * HTML fragments now correctly handle comments and CDATA blocks. GH #78
15
+ * Nokogiri::XML::Document#clone is now an alias of dup
16
+
17
+ * Deprecations
18
+
19
+ * Nokogiri::XML::SAX::Document#start_element_ns is deprecated, please switch
20
+ to Nokogiri::XML::SAX::Document#start_element_namespace
21
+ * Nokogiri::XML::SAX::Document#end_element_ns is deprecated, please switch
22
+ to Nokogiri::XML::SAX::Document#end_element_namespace
23
+
1
24
  === 1.3.1 / 2009-06-07
2
25
 
3
26
  * Bugfixes
data/Manifest.txt CHANGED
@@ -159,6 +159,7 @@ lib/nokogiri/xml/reader.rb
159
159
  lib/nokogiri/xml/relax_ng.rb
160
160
  lib/nokogiri/xml/sax.rb
161
161
  lib/nokogiri/xml/sax/document.rb
162
+ lib/nokogiri/xml/sax/legacy_handlers.rb
162
163
  lib/nokogiri/xml/sax/parser.rb
163
164
  lib/nokogiri/xml/sax/push_parser.rb
164
165
  lib/nokogiri/xml/schema.rb
@@ -177,14 +178,18 @@ test/css/test_xpath_visitor.rb
177
178
  test/ffi/test_document.rb
178
179
  test/files/address_book.rlx
179
180
  test/files/address_book.xml
181
+ test/files/bar/bar.xsd
180
182
  test/files/dont_hurt_em_why.xml
181
183
  test/files/exslt.xml
182
184
  test/files/exslt.xslt
185
+ test/files/foo/foo.xsd
183
186
  test/files/po.xml
184
187
  test/files/po.xsd
188
+ test/files/snuggles.xml
185
189
  test/files/staff.xml
186
190
  test/files/staff.xslt
187
191
  test/files/tlm.html
192
+ test/files/valid_bar.xml
188
193
  test/helper.rb
189
194
  test/hpricot/files/basic.xhtml
190
195
  test/hpricot/files/boingboing.html
data/README.ja.rdoc CHANGED
@@ -1,15 +1,15 @@
1
1
  = Nokogiri (鋸)
2
2
 
3
- * http://nokogiri.rubyforge.org/
3
+ * http://nokogiri.org/
4
4
  * http://github.com/tenderlove/nokogiri/wikis
5
5
  * http://github.com/tenderlove/nokogiri/tree/master
6
- * http://rubyforge.org/mailman/listinfo/nokogiri-talk
6
+ * http://groups.google.com/group/nokogiri-talk
7
7
  * http://github.com/tenderlove/nokogiri/issues
8
8
 
9
9
  == DESCRIPTION:
10
10
 
11
- Nokogiri はHTMLXMLSAXXSLTReaderのパーサーです。Nokogiri はドキュメント
12
- XPathCSS3 セレクター経由で検索する機能が特徴のひとつ。
11
+ Nokogiri はHTMLXMLSAXXSLTReaderのパーサーです。とりわけ重要な特徴は、
12
+ ドキュメントをXPathCSS3セレクター経由で探索する機能を持つことです。
13
13
 
14
14
  XMLは暴力に似ている - XMLが君の問題を解決しないとしたら、君はXMLを十分に
15
15
  使いこなしていない事になる。
@@ -32,7 +32,7 @@ XML/HTMLの高速な解析と探索検索、ならびにCSS3セレクタとXPath
32
32
 
33
33
  Nokogiriのメーリングリスト:
34
34
 
35
- * http://rubyforge.org/mailman/listinfo/nokogiri-talk
35
+ * http://groups.google.com/group/nokogiri-talk
36
36
 
37
37
  バグ報告:
38
38
 
data/README.rdoc CHANGED
@@ -1,9 +1,9 @@
1
1
  = Nokogiri
2
2
 
3
- * http://nokogiri.rubyforge.org/
3
+ * http://nokogiri.org/
4
4
  * http://github.com/tenderlove/nokogiri/wikis
5
5
  * http://github.com/tenderlove/nokogiri/tree/master
6
- * http://rubyforge.org/mailman/listinfo/nokogiri-talk
6
+ * http://groups.google.com/group/nokogiri-talk
7
7
  * http://github.com/tenderlove/nokogiri/issues
8
8
 
9
9
  == DESCRIPTION:
@@ -35,7 +35,7 @@ to using correct CSS and XPath.
35
35
 
36
36
  The Nokogiri mailing list is available here:
37
37
 
38
- * http://rubyforge.org/mailman/listinfo/nokogiri-talk
38
+ * http://groups.google.com/group/nokogiri-talk
39
39
 
40
40
  The bug tracker is available here:
41
41
 
data/Rakefile CHANGED
@@ -1,42 +1,39 @@
1
1
  # -*- ruby -*-
2
2
 
3
3
  require 'rubygems'
4
- require 'rake'
4
+ gem 'hoe', '>= 2.1.0'
5
5
  require 'hoe'
6
6
 
7
- LIB_DIR = File.expand_path(File.join(File.dirname(__FILE__), 'lib'))
8
- $LOAD_PATH << LIB_DIR
9
-
10
- windows = RUBY_PLATFORM =~ /(mswin|mingw)/i ? true : false
11
- java = RUBY_PLATFORM =~ /java/ ? true : false
7
+ windows = RUBY_PLATFORM =~ /(mswin|mingw)/i
8
+ java = RUBY_PLATFORM =~ /java/
12
9
 
13
10
  GENERATED_PARSER = "lib/nokogiri/css/generated_parser.rb"
14
11
  GENERATED_TOKENIZER = "lib/nokogiri/css/generated_tokenizer.rb"
15
12
 
16
- require 'nokogiri/version'
13
+ # Make sure hoe-debugging is installed
14
+ Hoe.plugin :debugging
17
15
 
18
- HOE = Hoe.new('nokogiri', Nokogiri::VERSION) do |p|
19
- p.developer('Aaron Patterson', 'aaronp@rubyforge.org')
20
- p.developer('Mike Dalessio', 'mike.dalessio@gmail.com')
21
- p.readme_file = ['README', ENV['HLANG'], 'rdoc'].compact.join('.')
22
- p.history_file = ['CHANGELOG', ENV['HLANG'], 'rdoc'].compact.join('.')
23
- p.extra_rdoc_files = FileList['*.rdoc']
24
- p.clean_globs = [
16
+ HOE = Hoe.spec 'nokogiri' do
17
+ developer('Aaron Patterson', 'aaronp@rubyforge.org')
18
+ developer('Mike Dalessio', 'mike.dalessio@gmail.com')
19
+ self.readme_file = ['README', ENV['HLANG'], 'rdoc'].compact.join('.')
20
+ self.history_file = ['CHANGELOG', ENV['HLANG'], 'rdoc'].compact.join('.')
21
+ self.extra_rdoc_files = FileList['*.rdoc']
22
+ self.clean_globs = [
25
23
  'lib/nokogiri/*.{o,so,bundle,a,log,dll}',
26
24
  GENERATED_PARSER,
27
25
  GENERATED_TOKENIZER,
28
26
  'cross',
29
27
  ]
30
28
 
31
- p.extra_dev_deps << "racc"
32
- p.extra_dev_deps << "rexical"
33
- p.extra_dev_deps << "rake-compiler"
29
+ %w{ racc rexical rake-compiler }.each do |dep|
30
+ extra_dev_deps << dep
31
+ end
34
32
 
35
- p.spec_extras = { :extensions => ["ext/nokogiri/extconf.rb"] }
33
+ self.spec_extras = { :extensions => ["ext/nokogiri/extconf.rb"] }
36
34
  end
37
35
 
38
36
  unless java
39
-
40
37
  gem 'rake-compiler', '>= 0.4.1'
41
38
  require "rake/extensiontask"
42
39
 
@@ -79,7 +76,7 @@ require "#{HOE.name}/\#{RUBY_VERSION.sub(/\\.\\d+$/, '')}/#{HOE.name}"
79
76
  HOE.spec.files += Dir["lib/#{HOE.name}/1.{8,9}/*"]
80
77
  HOE.spec.files += Dir["ext/nokogiri/*.dll"]
81
78
  end
82
- CLOBBER.include("lib/nokogiri/nokogiri.rb")
79
+ CLOBBER.include("lib/nokogiri/nokogiri.{so,dylib,rb,bundle}")
83
80
  CLOBBER.include("lib/nokogiri/1.{8,9}")
84
81
  end
85
82
 
@@ -184,9 +181,16 @@ unless windows || java || ENV['NOKOGIRI_FFI']
184
181
  end
185
182
 
186
183
  Rake::Task[:test].prerequisites << :compile
187
- ['valgrind', 'valgrind_mem', 'valgrind_mem0', 'coverage'].each do |task_name|
184
+ ['valgrind', 'valgrind:mem', 'valgrind:mem0'].each do |task_name|
188
185
  Rake::Task["test:#{task_name}"].prerequisites << :compile
189
186
  end
187
+ else
188
+ [:test, :check_manifest].each do |task_name|
189
+ if Rake::Task[task_name]
190
+ Rake::Task[task_name].prerequisites << GENERATED_PARSER
191
+ Rake::Task[task_name].prerequisites << GENERATED_TOKENIZER
192
+ end
193
+ end
190
194
  end
191
195
 
192
196
  namespace :install do
@@ -1,4 +1,4 @@
1
- ENV["ARCHFLAGS"] = "-arch #{`uname -p` =~ /powerpc/ ? 'ppc' : 'i386'}"
1
+ ENV['RC_ARCHS'] = '' if RUBY_PLATFORM =~ /darwin/
2
2
 
3
3
  require 'mkmf'
4
4
 
@@ -54,35 +54,60 @@ LIB_DIRS = [
54
54
  ]
55
55
 
56
56
  iconv_dirs = dir_config('iconv', '/opt/local/include', '/opt/local/lib')
57
- unless [nil, nil] == iconv_dirs
57
+ unless ["", ""] == iconv_dirs
58
58
  HEADER_DIRS.unshift iconv_dirs.first
59
59
  LIB_DIRS.unshift iconv_dirs[1]
60
60
  end
61
61
 
62
62
  xml2_dirs = dir_config('xml2', '/opt/local/include/libxml2', '/opt/local/lib')
63
- unless [nil, nil] == xml2_dirs
63
+ unless ["", ""] == xml2_dirs
64
64
  HEADER_DIRS.unshift xml2_dirs.first
65
65
  LIB_DIRS.unshift xml2_dirs[1]
66
66
  end
67
67
 
68
68
  xslt_dirs = dir_config('xslt', '/opt/local/include/', '/opt/local/lib')
69
- unless [nil, nil] == xslt_dirs
69
+ unless ["", ""] == xslt_dirs
70
70
  HEADER_DIRS.unshift xslt_dirs.first
71
71
  LIB_DIRS.unshift xslt_dirs[1]
72
72
  end
73
73
 
74
- unless find_header('iconv.h', *HEADER_DIRS)
74
+ CUSTOM_DASH_I = []
75
+
76
+ def nokogiri_find_header header_file, *paths
77
+ message = checking_message(header_file, paths)
78
+ header = cpp_include header_file
79
+ checking_for message do
80
+ found = false
81
+ paths.each do |dir|
82
+ if File.exists?(File.join(dir, header_file))
83
+ opt = "-I#{dir}".quote
84
+ if try_cpp header, opt
85
+ unless CUSTOM_DASH_I.include? dir
86
+ $INCFLAGS = "#{opt} #{$INCFLAGS}"
87
+ CUSTOM_DASH_I << dir
88
+ end
89
+ found = dir
90
+ break
91
+ end
92
+ end
93
+ end
94
+ found ||= try_cpp(header)
95
+ end
96
+ end
97
+
98
+ unless nokogiri_find_header('iconv.h', *HEADER_DIRS)
75
99
  abort "iconv is missing. try 'port install iconv' or 'yum install iconv'"
76
100
  end
77
101
 
78
- unless find_header('libxml/parser.h', *HEADER_DIRS)
102
+ unless nokogiri_find_header('libxml/parser.h', *HEADER_DIRS)
79
103
  abort "libxml2 is missing. try 'port install libxml2' or 'yum install libxml2-devel'"
80
104
  end
81
105
 
82
- unless find_header('libxslt/xslt.h', *HEADER_DIRS)
106
+ unless nokogiri_find_header('libxslt/xslt.h', *HEADER_DIRS)
83
107
  abort "libxslt is missing. try 'port install libxslt' or 'yum install libxslt-devel'"
84
108
  end
85
- unless find_header('libexslt/exslt.h', *HEADER_DIRS)
109
+
110
+ unless nokogiri_find_header('libexslt/exslt.h', *HEADER_DIRS)
86
111
  abort "libxslt is missing. try 'port install libxslt' or 'yum install libxslt-devel'"
87
112
  end
88
113
 
@@ -98,10 +123,27 @@ unless find_library('exslt', 'exsltFuncRegister', *LIB_DIRS)
98
123
  abort "libxslt is missing. try 'port install libxslt' or 'yum install libxslt-devel'"
99
124
  end
100
125
 
101
- have_func('xmlRelaxNGSetParserStructuredErrors')
102
- have_func('xmlRelaxNGSetValidStructuredErrors')
103
- have_func('xmlSchemaSetValidStructuredErrors')
104
- have_func('xmlSchemaSetParserStructuredErrors')
126
+ def nokogiri_link_command ldflags, opt='', libpath=$LIBPATH
127
+ old_link_command ldflags, opt, libpath
128
+ end
129
+
130
+ def with_custom_link
131
+ # alias :old_link_command :link_command
132
+ # alias :link_command :nokogiri_link_command
133
+ yield
134
+ #ensure
135
+ # alias :link_command :old_link_command
136
+ end
137
+
138
+ with_custom_link do
139
+ with_cppflags $INCFLAGS do
140
+ have_func('xmlRelaxNGSetParserStructuredErrors')
141
+ have_func('xmlRelaxNGSetParserStructuredErrors')
142
+ have_func('xmlRelaxNGSetValidStructuredErrors')
143
+ have_func('xmlSchemaSetValidStructuredErrors')
144
+ have_func('xmlSchemaSetParserStructuredErrors')
145
+ end
146
+ end
105
147
 
106
148
  if ENV['CPUPROFILE']
107
149
  unless find_library('profiler', 'ProfilerEnable', *LIB_DIRS)
@@ -296,12 +296,15 @@ VALUE Nokogiri_wrap_xml_document(VALUE klass, xmlDocPtr doc)
296
296
  dealloc,
297
297
  doc
298
298
  );
299
+
300
+ VALUE cache = rb_ary_new();
299
301
  rb_iv_set(rb_doc, "@decorators", Qnil);
300
- rb_iv_set(rb_doc, "@node_cache", rb_ary_new());
302
+ rb_iv_set(rb_doc, "@node_cache", cache);
301
303
  rb_funcall(rb_doc, rb_intern("initialize"), 0);
302
304
 
303
305
  tuple->doc = (void *)rb_doc;
304
306
  tuple->unlinkedNodes = xmlXPathNodeSetCreate(NULL);
307
+ tuple->node_cache = cache;
305
308
  doc->_private = tuple ;
306
309
 
307
310
  return rb_doc ;
@@ -6,6 +6,7 @@
6
6
  struct _nokogiriTuple {
7
7
  xmlDocPtr doc;
8
8
  xmlNodeSetPtr unlinkedNodes;
9
+ VALUE node_cache;
9
10
  };
10
11
  typedef struct _nokogiriTuple nokogiriTuple;
11
12
  typedef nokogiriTuple * nokogiriTuplePtr;
@@ -16,6 +17,7 @@ VALUE Nokogiri_wrap_xml_document(VALUE klass, xmlDocPtr doc);
16
17
  #define DOC_RUBY_OBJECT_TEST(x) ((nokogiriTuplePtr)(x->_private))
17
18
  #define DOC_RUBY_OBJECT(x) ((VALUE)((nokogiriTuplePtr)(x->_private))->doc)
18
19
  #define DOC_UNLINKED_NODE_SET(x) ((xmlNodeSetPtr)((nokogiriTuplePtr)(x->_private))->unlinkedNodes)
20
+ #define DOC_NODE_CACHE(x) ((VALUE)((nokogiriTuplePtr)(x->_private))->node_cache)
19
21
 
20
22
  extern VALUE cNokogiriXmlDocument ;
21
23
  #endif
@@ -85,6 +85,34 @@ static VALUE elements(VALUE self)
85
85
  return hash;
86
86
  }
87
87
 
88
+ /*
89
+ * call-seq:
90
+ * validate(document)
91
+ *
92
+ * Validate +document+ returning a list of errors
93
+ */
94
+ static VALUE validate(VALUE self, VALUE document)
95
+ {
96
+ xmlDocPtr doc;
97
+ xmlDtdPtr dtd;
98
+
99
+ Data_Get_Struct(self, xmlDtd, dtd);
100
+ Data_Get_Struct(document, xmlDoc, doc);
101
+ VALUE error_list = rb_ary_new();
102
+
103
+ xmlValidCtxtPtr ctxt = xmlNewValidCtxt();
104
+
105
+ xmlSetStructuredErrorFunc((void *)error_list, Nokogiri_error_array_pusher);
106
+
107
+ xmlValidateDtd(ctxt, doc, dtd);
108
+
109
+ xmlSetStructuredErrorFunc(NULL, NULL);
110
+
111
+ xmlFreeValidCtxt(ctxt);
112
+
113
+ return error_list;
114
+ }
115
+
88
116
  void init_xml_dtd()
89
117
  {
90
118
  VALUE nokogiri = rb_define_module("Nokogiri");
@@ -99,4 +127,5 @@ void init_xml_dtd()
99
127
  rb_define_method(klass, "notations", notations, 0);
100
128
  rb_define_method(klass, "elements", elements, 0);
101
129
  rb_define_method(klass, "entities", entities, 0);
130
+ rb_define_method(klass, "validate", validate, 1);
102
131
  }
@@ -720,6 +720,14 @@ static VALUE add_namespace_definition(VALUE self, VALUE prefix, VALUE href)
720
720
  (const xmlChar *)(prefix == Qnil ? NULL : StringValuePtr(prefix))
721
721
  );
722
722
 
723
+ if(!ns) {
724
+ ns = xmlSearchNs(
725
+ node->doc,
726
+ node,
727
+ (const xmlChar *)(prefix == Qnil ? NULL : StringValuePtr(prefix))
728
+ );
729
+ }
730
+
723
731
  if(Qnil == prefix) xmlSetNs(node, ns);
724
732
 
725
733
  return Nokogiri_wrap_xml_namespace(node->doc, ns);
@@ -849,7 +857,7 @@ VALUE Nokogiri_wrap_xml_node(VALUE klass, xmlNodePtr node)
849
857
 
850
858
  if (DOC_RUBY_OBJECT_TEST(node->doc) && DOC_RUBY_OBJECT(node->doc)) {
851
859
  document = DOC_RUBY_OBJECT(node->doc);
852
- node_cache = rb_iv_get(document, "@node_cache");
860
+ node_cache = DOC_NODE_CACHE(node->doc);
853
861
  }
854
862
 
855
863
  rb_ary_push(node_cache, rb_node);
@@ -145,7 +145,11 @@ static VALUE plus(VALUE self, VALUE rb_other)
145
145
  new = xmlXPathNodeSetMerge(NULL, node_set);
146
146
  new = xmlXPathNodeSetMerge(new, other);
147
147
 
148
- return Nokogiri_wrap_xml_node_set(new);
148
+ VALUE new_set = Nokogiri_wrap_xml_node_set(new);
149
+
150
+ rb_iv_set(new_set, "@document", rb_iv_get(self, "@document"));
151
+
152
+ return new_set;
149
153
  }
150
154
 
151
155
  /*
@@ -77,9 +77,55 @@ static VALUE read_memory(VALUE klass, VALUE content)
77
77
  if(NULL == schema) {
78
78
  xmlErrorPtr error = xmlGetLastError();
79
79
  if(error)
80
- rb_funcall(rb_mKernel, rb_intern("raise"), 1,
81
- Nokogiri_wrap_xml_syntax_error((VALUE)NULL, error)
82
- );
80
+ Nokogiri_error_raise(NULL, error);
81
+ else
82
+ rb_raise(rb_eRuntimeError, "Could not parse document");
83
+
84
+ return Qnil;
85
+ }
86
+
87
+ VALUE rb_schema = Data_Wrap_Struct(klass, 0, dealloc, schema);
88
+ rb_iv_set(rb_schema, "@errors", errors);
89
+
90
+ return rb_schema;
91
+ }
92
+
93
+ /*
94
+ * call-seq:
95
+ * from_document(doc)
96
+ *
97
+ * Create a new RelaxNG schema from the Nokogiri::XML::Document +doc+
98
+ */
99
+ static VALUE from_document(VALUE klass, VALUE document)
100
+ {
101
+ xmlDocPtr doc;
102
+ Data_Get_Struct(document, xmlDoc, doc);
103
+
104
+ // In case someone passes us a node. ugh.
105
+ doc = doc->doc;
106
+
107
+ xmlRelaxNGParserCtxtPtr ctx = xmlRelaxNGNewDocParserCtxt(doc);
108
+
109
+ VALUE errors = rb_ary_new();
110
+ xmlSetStructuredErrorFunc((void *)errors, Nokogiri_error_array_pusher);
111
+
112
+ #ifdef HAVE_XMLRELAXNGSETPARSERSTRUCTUREDERRORS
113
+ xmlRelaxNGSetParserStructuredErrors(
114
+ ctx,
115
+ Nokogiri_error_array_pusher,
116
+ (void *)errors
117
+ );
118
+ #endif
119
+
120
+ xmlRelaxNGPtr schema = xmlRelaxNGParse(ctx);
121
+
122
+ xmlSetStructuredErrorFunc(NULL, NULL);
123
+ xmlRelaxNGFreeParserCtxt(ctx);
124
+
125
+ if(NULL == schema) {
126
+ xmlErrorPtr error = xmlGetLastError();
127
+ if(error)
128
+ Nokogiri_error_raise(NULL, error);
83
129
  else
84
130
  rb_raise(rb_eRuntimeError, "Could not parse document");
85
131
 
@@ -102,5 +148,6 @@ void init_xml_relax_ng()
102
148
  cNokogiriXmlRelaxNG = klass;
103
149
 
104
150
  rb_define_singleton_method(klass, "read_memory", read_memory, 1);
151
+ rb_define_singleton_method(klass, "from_document", from_document, 1);
105
152
  rb_define_private_method(klass, "validate_document", validate_document, 1);
106
153
  }