nokogiri 1.3.2 → 1.3.3

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 (66) hide show
  1. data/CHANGELOG.ja.rdoc +25 -4
  2. data/CHANGELOG.rdoc +20 -0
  3. data/Manifest.txt +2 -0
  4. data/Rakefile +20 -21
  5. data/ext/nokogiri/extconf.rb +8 -1
  6. data/ext/nokogiri/html_document.c +0 -2
  7. data/ext/nokogiri/nokogiri.c +2 -0
  8. data/ext/nokogiri/nokogiri.h +3 -4
  9. data/ext/nokogiri/xml_document.c +30 -23
  10. data/ext/nokogiri/xml_document.h +3 -2
  11. data/ext/nokogiri/xml_dtd.c +4 -0
  12. data/ext/nokogiri/xml_dtd.h +2 -0
  13. data/ext/nokogiri/xml_node.c +28 -9
  14. data/ext/nokogiri/xml_reader.c +0 -7
  15. data/ext/nokogiri/xml_relax_ng.c +7 -1
  16. data/ext/nokogiri/xml_sax_parser.c +2 -0
  17. data/lib/action-nokogiri.rb +2 -0
  18. data/lib/nokogiri.rb +9 -3
  19. data/lib/nokogiri/css/generated_tokenizer.rb +80 -82
  20. data/lib/nokogiri/css/tokenizer.rb +1 -5
  21. data/lib/nokogiri/decorators/hpricot/node_set.rb +1 -1
  22. data/lib/nokogiri/ffi/structs/common_node.rb +1 -1
  23. data/lib/nokogiri/ffi/structs/xml_document.rb +1 -1
  24. data/lib/nokogiri/ffi/xml/document.rb +15 -4
  25. data/lib/nokogiri/ffi/xml/node.rb +85 -63
  26. data/lib/nokogiri/ffi/xml/reader.rb +4 -15
  27. data/lib/nokogiri/ffi/xml/relax_ng.rb +3 -1
  28. data/lib/nokogiri/hpricot.rb +30 -0
  29. data/lib/nokogiri/html/document.rb +3 -1
  30. data/lib/nokogiri/html/document_fragment.rb +1 -1
  31. data/lib/nokogiri/html/sax/parser.rb +2 -1
  32. data/lib/nokogiri/version.rb +1 -1
  33. data/lib/nokogiri/xml/builder.rb +44 -1
  34. data/lib/nokogiri/xml/document.rb +8 -1
  35. data/lib/nokogiri/xml/document_fragment.rb +1 -1
  36. data/lib/nokogiri/xml/fragment_handler.rb +4 -7
  37. data/lib/nokogiri/xml/node.rb +9 -6
  38. data/lib/nokogiri/xml/node_set.rb +7 -0
  39. data/lib/nokogiri/xml/parse_options.rb +1 -1
  40. data/test/css/test_nthiness.rb +2 -3
  41. data/test/ffi/test_document.rb +6 -6
  42. data/test/files/2ch.html +108 -0
  43. data/test/files/shift_jis.xml +5 -0
  44. data/test/helper.rb +3 -0
  45. data/test/hpricot/test_alter.rb +9 -9
  46. data/test/hpricot/test_builder.rb +2 -2
  47. data/test/hpricot/test_parser.rb +70 -146
  48. data/test/hpricot/test_paths.rb +2 -2
  49. data/test/hpricot/test_preserved.rb +2 -2
  50. data/test/hpricot/test_xml.rb +3 -3
  51. data/test/html/sax/test_parser.rb +12 -0
  52. data/test/html/test_builder.rb +6 -4
  53. data/test/html/test_document.rb +7 -0
  54. data/test/html/test_document_encoding.rb +17 -0
  55. data/test/html/test_document_fragment.rb +12 -0
  56. data/test/html/test_node.rb +5 -2
  57. data/test/test_convert_xpath.rb +1 -50
  58. data/test/test_css_cache.rb +1 -12
  59. data/test/test_nokogiri.rb +7 -0
  60. data/test/test_reader.rb +14 -0
  61. data/test/xml/test_document.rb +44 -0
  62. data/test/xml/test_document_fragment.rb +12 -0
  63. data/test/xml/test_node.rb +10 -2
  64. data/test/xml/test_node_encoding.rb +23 -0
  65. data/test/xml/test_node_set.rb +10 -0
  66. metadata +5 -3
@@ -1,3 +1,24 @@
1
+ === 1.3.3 / 2009年7月26日
2
+
3
+ * 新しい機能
4
+
5
+ * NodeSet#children 全ての子ノードを返すようになった
6
+
7
+ * バグの修正
8
+
9
+ * libxml-ruby のグローバ ルエラー ハンドラー に優先するようになった
10
+ * ParseOption#strict を修正
11
+ * 空のstringを Node#inner_html= に与えた時に生じたSEGVを修正 GH #88
12
+ * Ruby 1.9 で返したStringのエンコードはUTF-8になった
13
+ * ドキュメントの根ノードから違うドキュメントの根ノードに移動した時に生じた
14
+ SEGVを修正 GH #91
15
+ * ノードをインスタンス化する時のO(n)のペナルティーを修正 GH #101
16
+ * XMLのドキュメントをHTMLのドキュメントととして出力出来るようになった
17
+
18
+ * 廃棄予定
19
+
20
+ * Hpricotの互換性レイヤーがNokogiriの1.4.0で除去される予定
21
+
1
22
  === 1.3.2 / 2009年6月22日
2
23
 
3
24
  * 新しい機能
@@ -9,12 +30,12 @@
9
30
  * Nokogiri::XML::NodeSet#search はトップレベルのノードを検索するようになった
10
31
  GH #73
11
32
  * Nokogiri::XML::Documentからメソッドに関係する名前空間を取り除いた
12
- * 同じ名前空間を2回目に入れた時に起るセグフォールトを修正した
13
- * Snow Leopard で Nokogiri は動くようになった GH #79
14
- * メーリングリストはGoogle Groupsの以下のアドレスに移動した
33
+ * 2回同じ名前空間が追加されたときSEGVする問題を修正した
34
+ * Snow Leopard で Nokogiri が動くようになった GH #79
35
+ * メーリングリストはGoogle Groupsの以下のURLに移動した
15
36
  http://groups.google.com/group/nokogiri-talk
16
37
  * HTML フラグメントはコメントとCDATAを正確に扱うようになった
17
- * Nokogiri::XML::Document#cloneはdupのエイリアスと同様の働きをする
38
+ * Nokogiri::XML::Document#cloneはdupのaliasになった
18
39
 
19
40
  * 廃棄予定
20
41
 
@@ -1,3 +1,23 @@
1
+ === 1.3.3 / 2009/07/26
2
+
3
+ * New Features
4
+
5
+ * NodeSet#children returns all children of all nodes
6
+
7
+ * Bugfixes
8
+
9
+ * Override libxml-ruby's global error handler
10
+ * ParseOption#strict fixed
11
+ * Fixed a segfault when sending an empty string to Node#inner_html= GH #88
12
+ * String encoding is now set to UTF-8 in Ruby 1.9
13
+ * Fixed a segfault when moving root nodes between documents. GH #91
14
+ * Fixed an O(n) penalty on node creation. GH #101
15
+ * Allowing XML documents to be output as HTML documents
16
+
17
+ * Deprecations
18
+
19
+ * Hpricot compatibility layer will be removed in 1.4.0
20
+
1
21
  === 1.3.2 / 2009-06-22
2
22
 
3
23
  * New Features
@@ -176,6 +176,7 @@ test/css/test_parser.rb
176
176
  test/css/test_tokenizer.rb
177
177
  test/css/test_xpath_visitor.rb
178
178
  test/ffi/test_document.rb
179
+ test/files/2ch.html
179
180
  test/files/address_book.rlx
180
181
  test/files/address_book.xml
181
182
  test/files/bar/bar.xsd
@@ -185,6 +186,7 @@ test/files/exslt.xslt
185
186
  test/files/foo/foo.xsd
186
187
  test/files/po.xml
187
188
  test/files/po.xsd
189
+ test/files/shift_jis.xml
188
190
  test/files/snuggles.xml
189
191
  test/files/staff.xml
190
192
  test/files/staff.xslt
data/Rakefile CHANGED
@@ -27,7 +27,7 @@ HOE = Hoe.spec 'nokogiri' do
27
27
  ]
28
28
 
29
29
  %w{ racc rexical rake-compiler }.each do |dep|
30
- extra_dev_deps << dep
30
+ self.extra_dev_deps << dep
31
31
  end
32
32
 
33
33
  self.spec_extras = { :extensions => ["ext/nokogiri/extconf.rb"] }
@@ -52,30 +52,23 @@ unless java
52
52
  "--with-xslt-dir=#{File.join(cross_dir, 'libxslt')}"
53
53
  end
54
54
 
55
- ###
56
- # To build the windows fat binary, do:
57
- #
58
- # rake fat_binary native gem
59
- #
60
- # I keep my ruby in multiruby, so my command is like this:
61
- #
62
- # RAKE19=~/.multiruby/install/1.9.1-p129/bin/rake \
63
- # rake fat_binary native gem
64
- task 'fat_binary' do
65
- rake19 = ENV['RAKE19'] || 'rake1.9'
66
- system("rake clean cross compile RUBY_CC_VERSION=1.8.6 FAT_DIR=1.8")
67
- system("#{rake19} clean cross compile RUBY_CC_VERSION=1.9.1 FAT_DIR=1.9")
55
+ file 'lib/nokogiri/nokogiri.rb' do
68
56
  File.open("lib/#{HOE.name}/#{HOE.name}.rb", 'wb') do |f|
69
57
  f.write <<-eoruby
70
58
  require "#{HOE.name}/\#{RUBY_VERSION.sub(/\\.\\d+$/, '')}/#{HOE.name}"
71
59
  eoruby
72
60
  end
73
- HOE.spec.extensions = []
74
- HOE.spec.platform = 'x86-mingw32'
75
- HOE.spec.files += Dir["lib/#{HOE.name}/#{HOE.name}.rb"]
76
- HOE.spec.files += Dir["lib/#{HOE.name}/1.{8,9}/*"]
77
- HOE.spec.files += Dir["ext/nokogiri/*.dll"]
78
61
  end
62
+
63
+ namespace :cross do
64
+ task :file_list do
65
+ HOE.spec.platform = 'x86-mswin32'
66
+ HOE.spec.extensions = []
67
+ HOE.spec.files += Dir["lib/#{HOE.name}/#{HOE.name}.rb"]
68
+ HOE.spec.files += Dir["ext/nokogiri/*.dll"]
69
+ end
70
+ end
71
+
79
72
  CLOBBER.include("lib/nokogiri/nokogiri.{so,dylib,rb,bundle}")
80
73
  CLOBBER.include("lib/nokogiri/1.{8,9}")
81
74
  end
@@ -146,6 +139,7 @@ libs.each do |lib|
146
139
  system("wget #{url} || curl -O #{url}")
147
140
  end
148
141
  end
142
+
149
143
  file "tmp/cross/#{lib.split('-').first}" => ["tmp/stash/#{lib}.zip"] do |t|
150
144
  puts "unzipping #{lib}.zip"
151
145
  FileUtils.mkdir_p('tmp/cross')
@@ -157,8 +151,11 @@ libs.each do |lib|
157
151
  sh "touch #{lib.split('-').first}"
158
152
  end
159
153
  end
154
+
160
155
  if Rake::Task.task_defined?(:cross)
161
156
  Rake::Task[:cross].prerequisites << "tmp/cross/#{lib.split('-').first}"
157
+ Rake::Task[:cross].prerequisites << "lib/nokogiri/nokogiri.rb"
158
+ Rake::Task[:cross].prerequisites << "cross:file_list"
162
159
  end
163
160
  end
164
161
 
@@ -181,8 +178,10 @@ unless windows || java || ENV['NOKOGIRI_FFI']
181
178
  end
182
179
 
183
180
  Rake::Task[:test].prerequisites << :compile
184
- ['valgrind', 'valgrind:mem', 'valgrind:mem0'].each do |task_name|
185
- Rake::Task["test:#{task_name}"].prerequisites << :compile
181
+ if Hoe.plugins.include?(:debugging)
182
+ ['valgrind', 'valgrind:mem', 'valgrind:mem0'].each do |task_name|
183
+ Rake::Task["test:#{task_name}"].prerequisites << :compile
184
+ end
186
185
  end
187
186
  else
188
187
  [:test, :check_manifest].each do |task_name|
@@ -1,5 +1,7 @@
1
1
  ENV['RC_ARCHS'] = '' if RUBY_PLATFORM =~ /darwin/
2
2
 
3
+ # :stopdoc:
4
+
3
5
  require 'mkmf'
4
6
 
5
7
  ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
@@ -74,7 +76,11 @@ end
74
76
  CUSTOM_DASH_I = []
75
77
 
76
78
  def nokogiri_find_header header_file, *paths
77
- message = checking_message(header_file, paths)
79
+ # mkmf in ruby 1.8.5 does not have the "checking_message" method
80
+ message = defined?(checking_message) ?
81
+ checking_message(header_file, paths) :
82
+ header_file
83
+
78
84
  header = cpp_include header_file
79
85
  checking_for message do
80
86
  found = false
@@ -152,3 +158,4 @@ if ENV['CPUPROFILE']
152
158
  end
153
159
 
154
160
  create_makefile('nokogiri/nokogiri')
161
+ # :startdoc:
@@ -40,7 +40,6 @@ static VALUE read_io( VALUE klass,
40
40
  const char * c_enc = (encoding == Qnil) ? NULL : StringValuePtr(encoding);
41
41
  VALUE error_list = rb_ary_new();
42
42
 
43
- xmlInitParser();
44
43
  xmlResetLastError();
45
44
  xmlSetStructuredErrorFunc((void *)error_list, Nokogiri_error_array_pusher);
46
45
 
@@ -92,7 +91,6 @@ static VALUE read_memory( VALUE klass,
92
91
  int len = RSTRING_LEN(string);
93
92
  VALUE error_list = rb_ary_new();
94
93
 
95
- xmlInitParser();
96
94
  xmlResetLastError();
97
95
  xmlSetStructuredErrorFunc((void *)error_list, Nokogiri_error_array_pusher);
98
96
 
@@ -53,6 +53,8 @@ void Init_nokogiri()
53
53
  NOKOGIRI_STR_NEW2(xmlParserVersion, "UTF-8")
54
54
  );
55
55
 
56
+ xmlInitParser();
57
+
56
58
  init_xml_document();
57
59
  init_html_document();
58
60
  init_xml_node();
@@ -46,7 +46,7 @@ int is_2_6_16(void) ;
46
46
  ({ \
47
47
  VALUE _string = rb_str_new2((const char *)str); \
48
48
  if(NULL != encoding) { \
49
- int _enc = rb_enc_find_index(encoding); \
49
+ int _enc = rb_enc_find_index("UTF-8"); \
50
50
  if(_enc == -1) \
51
51
  rb_enc_associate_index(_string, rb_enc_find_index("ASCII")); \
52
52
  else \
@@ -59,7 +59,7 @@ int is_2_6_16(void) ;
59
59
  ({ \
60
60
  VALUE _string = rb_str_new((const char *)str, (long)len); \
61
61
  if(NULL != encoding) { \
62
- int _enc = rb_enc_find_index(encoding); \
62
+ int _enc = rb_enc_find_index("UTF-8"); \
63
63
  if(_enc == -1) \
64
64
  rb_enc_associate_index(_string, rb_enc_find_index("ASCII")); \
65
65
  else \
@@ -114,8 +114,7 @@ extern VALUE mNokogiriXslt ;
114
114
  #define NOKOGIRI_ROOT_NODE(_node) \
115
115
  ({ \
116
116
  nokogiriTuplePtr tuple = (nokogiriTuplePtr)(_node->doc->_private); \
117
- xmlNodeSetPtr node_set = (xmlNodeSetPtr)(tuple->unlinkedNodes); \
118
- xmlXPathNodeSetAdd(node_set, _node); \
117
+ st_insert(tuple->unlinkedNodes, (st_data_t)_node, (st_data_t)_node); \
119
118
  _node; \
120
119
  })
121
120
 
@@ -1,32 +1,29 @@
1
1
  #include <xml_document.h>
2
2
 
3
+ static int dealloc_node_i(xmlNodePtr key, xmlNodePtr node, xmlDocPtr doc)
4
+ {
5
+ switch(node->type) {
6
+ case XML_ATTRIBUTE_NODE:
7
+ xmlFreePropList((xmlAttrPtr)node);
8
+ break;
9
+ default:
10
+ if(node->parent == NULL) {
11
+ xmlAddChild((xmlNodePtr)doc, node);
12
+ }
13
+ }
14
+ return ST_CONTINUE;
15
+ }
16
+
3
17
  static void dealloc(xmlDocPtr doc)
4
18
  {
5
19
  NOKOGIRI_DEBUG_START(doc);
6
20
 
7
- nokogiriTuplePtr tuple = doc->_private;
8
- xmlNodeSetPtr node_set = tuple->unlinkedNodes;
21
+ st_table *node_hash = DOC_UNLINKED_NODE_HASH(doc);
9
22
 
10
23
  xmlDeregisterNodeFunc func = xmlDeregisterNodeDefault(NULL);
11
24
 
12
- int j ;
13
- for(j = 0 ; j < node_set->nodeNr ; j++) {
14
- xmlNodePtr node = node_set->nodeTab[j];
15
- switch(node->type)
16
- {
17
- case XML_ATTRIBUTE_NODE:
18
- xmlFreePropList((xmlAttrPtr)node);
19
- break;
20
- default:
21
- if(node->parent == NULL) {
22
- xmlAddChild((xmlNodePtr)doc, node);
23
- }
24
- }
25
- }
26
-
27
- if (node_set->nodeTab != NULL)
28
- xmlFree(node_set->nodeTab);
29
- xmlFree(node_set);
25
+ st_foreach(node_hash, dealloc_node_i, (st_data_t)doc);
26
+ st_free_table(node_hash);
30
27
 
31
28
  free(doc->_private);
32
29
  doc->_private = NULL;
@@ -68,7 +65,19 @@ static VALUE set_root(VALUE self, VALUE root)
68
65
  Data_Get_Struct(self, xmlDoc, doc);
69
66
  Data_Get_Struct(root, xmlNode, new_root);
70
67
 
68
+ xmlNodePtr old_root = NULL;
69
+
70
+ /* If the new root's document is not the same as the current document,
71
+ * then we need to dup the node in to this document. */
72
+ if(new_root->doc != doc) {
73
+ old_root = xmlDocGetRootElement(doc);
74
+ if (!(new_root = xmlDocCopyNode(new_root, doc, 1))) {
75
+ rb_raise(rb_eRuntimeError, "Could not reparent node (xmlDocCopyNode)");
76
+ }
77
+ }
78
+
71
79
  xmlDocSetRootElement(doc, new_root);
80
+ if(old_root) NOKOGIRI_ROOT_NODE(old_root);
72
81
  return root;
73
82
  }
74
83
 
@@ -136,7 +145,6 @@ static VALUE read_io( VALUE klass,
136
145
  const char * c_enc = (encoding == Qnil) ? NULL : StringValuePtr(encoding);
137
146
  VALUE error_list = rb_ary_new();
138
147
 
139
- xmlInitParser();
140
148
  xmlResetLastError();
141
149
  xmlSetStructuredErrorFunc((void *)error_list, Nokogiri_error_array_pusher);
142
150
 
@@ -187,7 +195,6 @@ static VALUE read_memory( VALUE klass,
187
195
  int len = RSTRING_LEN(string);
188
196
  VALUE error_list = rb_ary_new();
189
197
 
190
- xmlInitParser();
191
198
  xmlResetLastError();
192
199
  xmlSetStructuredErrorFunc((void *)error_list, Nokogiri_error_array_pusher);
193
200
  xmlDocPtr doc = xmlReadMemory(c_buffer, len, c_url, c_enc, NUM2INT(options));
@@ -303,7 +310,7 @@ VALUE Nokogiri_wrap_xml_document(VALUE klass, xmlDocPtr doc)
303
310
  rb_funcall(rb_doc, rb_intern("initialize"), 0);
304
311
 
305
312
  tuple->doc = (void *)rb_doc;
306
- tuple->unlinkedNodes = xmlXPathNodeSetCreate(NULL);
313
+ tuple->unlinkedNodes = st_init_numtable_with_size(128);
307
314
  tuple->node_cache = cache;
308
315
  doc->_private = tuple ;
309
316
 
@@ -2,10 +2,11 @@
2
2
  #define NOKOGIRI_XML_DOCUMENT
3
3
 
4
4
  #include <nokogiri.h>
5
+ #include "st.h"
5
6
 
6
7
  struct _nokogiriTuple {
7
8
  xmlDocPtr doc;
8
- xmlNodeSetPtr unlinkedNodes;
9
+ st_table *unlinkedNodes;
9
10
  VALUE node_cache;
10
11
  };
11
12
  typedef struct _nokogiriTuple nokogiriTuple;
@@ -16,7 +17,7 @@ VALUE Nokogiri_wrap_xml_document(VALUE klass, xmlDocPtr doc);
16
17
 
17
18
  #define DOC_RUBY_OBJECT_TEST(x) ((nokogiriTuplePtr)(x->_private))
18
19
  #define DOC_RUBY_OBJECT(x) ((VALUE)((nokogiriTuplePtr)(x->_private))->doc)
19
- #define DOC_UNLINKED_NODE_SET(x) ((xmlNodeSetPtr)((nokogiriTuplePtr)(x->_private))->unlinkedNodes)
20
+ #define DOC_UNLINKED_NODE_HASH(x) (((nokogiriTuplePtr)(x->_private))->unlinkedNodes)
20
21
  #define DOC_NODE_CACHE(x) ((VALUE)((nokogiriTuplePtr)(x->_private))->node_cache)
21
22
 
22
23
  extern VALUE cNokogiriXmlDocument ;
@@ -113,6 +113,8 @@ static VALUE validate(VALUE self, VALUE document)
113
113
  return error_list;
114
114
  }
115
115
 
116
+ VALUE cNokogiriXmlDtd;
117
+
116
118
  void init_xml_dtd()
117
119
  {
118
120
  VALUE nokogiri = rb_define_module("Nokogiri");
@@ -124,6 +126,8 @@ void init_xml_dtd()
124
126
  */
125
127
  VALUE klass = rb_define_class_under(xml, "DTD", node);
126
128
 
129
+ cNokogiriXmlDtd = klass;
130
+
127
131
  rb_define_method(klass, "notations", notations, 0);
128
132
  rb_define_method(klass, "elements", elements, 0);
129
133
  rb_define_method(klass, "entities", entities, 0);
@@ -3,6 +3,8 @@
3
3
 
4
4
  #include <nokogiri.h>
5
5
 
6
+ extern VALUE cNokogiriXmlDtd;
7
+
6
8
  void init_xml_dtd();
7
9
 
8
10
  #endif
@@ -12,7 +12,10 @@ static void debug_node_dealloc(xmlNodePtr x)
12
12
 
13
13
  static void mark(xmlNodePtr node)
14
14
  {
15
- rb_gc_mark(DOC_RUBY_OBJECT(node->doc));
15
+ // it's OK if the document isn't fully realized (as in XML::Reader).
16
+ // see http://github.com/tenderlove/nokogiri/issues/closed/#issue/95
17
+ if (DOC_RUBY_OBJECT_TEST(node->doc) && DOC_RUBY_OBJECT(node->doc))
18
+ rb_gc_mark(DOC_RUBY_OBJECT(node->doc));
16
19
  }
17
20
 
18
21
  /* :nodoc: */
@@ -60,6 +63,17 @@ static VALUE reparent_node_with(VALUE node_obj, VALUE other_obj, node_other_func
60
63
  Data_Get_Struct(node_obj, xmlNode, node);
61
64
  Data_Get_Struct(other_obj, xmlNode, other);
62
65
 
66
+ // If a document fragment is added, we need to reparent all of it's children
67
+ if(node->type == XML_DOCUMENT_FRAG_NODE)
68
+ {
69
+ xmlNodePtr child = node->children;
70
+ while(NULL != child) {
71
+ reparent_node_with(Nokogiri_wrap_xml_node((VALUE)NULL, child), other_obj, func);
72
+ child = child->next;
73
+ }
74
+ return node_obj;
75
+ }
76
+
63
77
  if (node->doc == other->doc) {
64
78
  xmlUnlinkNode(node) ;
65
79
  if ( node->type == XML_TEXT_NODE
@@ -673,6 +687,8 @@ static VALUE native_write_to(
673
687
 
674
688
  xmlIndentTreeOutput = 1;
675
689
 
690
+ const char * before_indent = xmlTreeIndentString;
691
+
676
692
  xmlTreeIndentString = StringValuePtr(indent_string);
677
693
 
678
694
  xmlSaveCtxtPtr savectx = xmlSaveToIO(
@@ -685,6 +701,8 @@ static VALUE native_write_to(
685
701
 
686
702
  xmlSaveTree(savectx, node);
687
703
  xmlSaveClose(savectx);
704
+
705
+ xmlTreeIndentString = before_indent;
688
706
  return io;
689
707
  }
690
708
 
@@ -754,7 +772,10 @@ static VALUE new(int argc, VALUE *argv, VALUE klass)
754
772
  node->doc = doc->doc;
755
773
  NOKOGIRI_ROOT_NODE(node);
756
774
 
757
- VALUE rb_node = Nokogiri_wrap_xml_node(klass, node);
775
+ VALUE rb_node = Nokogiri_wrap_xml_node(
776
+ klass == cNokogiriXmlNode ? (VALUE)NULL : klass,
777
+ node
778
+ );
758
779
  rb_funcall2(rb_node, rb_intern("initialize"), argc, argv);
759
780
 
760
781
  if(rb_block_given_p()) rb_yield(rb_node);
@@ -774,9 +795,6 @@ static VALUE dump_html(VALUE self)
774
795
  xmlNodePtr node ;
775
796
  Data_Get_Struct(self, xmlNode, node);
776
797
 
777
- if(node->doc->type == XML_DOCUMENT_NODE)
778
- return rb_funcall(self, rb_intern("to_xml"), 0);
779
-
780
798
  buf = xmlBufferCreate() ;
781
799
  htmlNodeDump(buf, node->doc, node);
782
800
  VALUE html = NOKOGIRI_STR_NEW2(buf->content, node->doc->encoding);
@@ -845,7 +863,7 @@ VALUE Nokogiri_wrap_xml_node(VALUE klass, xmlNodePtr node)
845
863
  klass = cNokogiriXmlCData;
846
864
  break;
847
865
  case XML_DTD_NODE:
848
- klass = rb_const_get(mNokogiriXml, rb_intern("DTD"));
866
+ klass = cNokogiriXmlDtd;
849
867
  break;
850
868
  default:
851
869
  klass = cNokogiriXmlNode;
@@ -856,13 +874,14 @@ VALUE Nokogiri_wrap_xml_node(VALUE klass, xmlNodePtr node)
856
874
  node->_private = (void *)rb_node;
857
875
 
858
876
  if (DOC_RUBY_OBJECT_TEST(node->doc) && DOC_RUBY_OBJECT(node->doc)) {
877
+ // it's OK if the document isn't fully realized (as in XML::Reader).
878
+ // see http://github.com/tenderlove/nokogiri/issues/closed/#issue/95
859
879
  document = DOC_RUBY_OBJECT(node->doc);
860
880
  node_cache = DOC_NODE_CACHE(node->doc);
881
+ rb_ary_push(node_cache, rb_node);
882
+ rb_funcall(document, rb_intern("decorate"), 1, rb_node);
861
883
  }
862
884
 
863
- rb_ary_push(node_cache, rb_node);
864
- rb_funcall(document, rb_intern("decorate"), 1, rb_node);
865
-
866
885
  return rb_node ;
867
886
  }
868
887