nokogiri 1.4.1-x86-mswin32 → 1.4.2.1-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 (112) hide show
  1. data/CHANGELOG.ja.rdoc +45 -0
  2. data/CHANGELOG.rdoc +53 -1
  3. data/Manifest.txt +3 -3
  4. data/README.ja.rdoc +1 -1
  5. data/README.rdoc +11 -5
  6. data/Rakefile +13 -79
  7. data/ext/nokogiri/extconf.rb +25 -74
  8. data/ext/nokogiri/html_document.c +17 -8
  9. data/ext/nokogiri/html_element_description.c +20 -16
  10. data/ext/nokogiri/html_entity_lookup.c +2 -2
  11. data/ext/nokogiri/html_sax_parser_context.c +10 -8
  12. data/ext/nokogiri/nokogiri.c +0 -1
  13. data/ext/nokogiri/nokogiri.h +33 -28
  14. data/ext/nokogiri/xml_attr.c +7 -5
  15. data/ext/nokogiri/xml_attribute_decl.c +5 -2
  16. data/ext/nokogiri/xml_cdata.c +4 -2
  17. data/ext/nokogiri/xml_comment.c +4 -2
  18. data/ext/nokogiri/xml_document.c +93 -15
  19. data/ext/nokogiri/xml_document.h +0 -1
  20. data/ext/nokogiri/xml_document_fragment.c +4 -2
  21. data/ext/nokogiri/xml_dtd.c +18 -8
  22. data/ext/nokogiri/xml_element_content.c +2 -2
  23. data/ext/nokogiri/xml_entity_decl.c +15 -2
  24. data/ext/nokogiri/xml_entity_reference.c +4 -2
  25. data/ext/nokogiri/xml_io.c +1 -1
  26. data/ext/nokogiri/xml_namespace.c +5 -3
  27. data/ext/nokogiri/xml_node.c +353 -114
  28. data/ext/nokogiri/xml_node_set.c +35 -22
  29. data/ext/nokogiri/xml_node_set.h +1 -1
  30. data/ext/nokogiri/xml_processing_instruction.c +4 -2
  31. data/ext/nokogiri/xml_reader.c +119 -47
  32. data/ext/nokogiri/xml_relax_ng.c +21 -12
  33. data/ext/nokogiri/xml_sax_parser.c +6 -3
  34. data/ext/nokogiri/xml_sax_parser.h +13 -17
  35. data/ext/nokogiri/xml_sax_parser_context.c +8 -6
  36. data/ext/nokogiri/xml_sax_push_parser.c +7 -6
  37. data/ext/nokogiri/xml_schema.c +62 -13
  38. data/ext/nokogiri/xml_syntax_error.c +18 -12
  39. data/ext/nokogiri/xml_syntax_error.h +1 -1
  40. data/ext/nokogiri/xml_text.c +4 -2
  41. data/ext/nokogiri/xml_xpath_context.c +60 -23
  42. data/ext/nokogiri/xslt_stylesheet.c +14 -3
  43. data/lib/nokogiri.rb +17 -0
  44. data/lib/nokogiri/1.8/nokogiri.so +0 -0
  45. data/lib/nokogiri/1.9/nokogiri.so +0 -0
  46. data/lib/nokogiri/css/generated_parser.rb +72 -62
  47. data/lib/nokogiri/css/generated_tokenizer.rb +23 -23
  48. data/lib/nokogiri/css/parser.y +3 -1
  49. data/lib/nokogiri/css/tokenizer.rex +3 -3
  50. data/lib/nokogiri/css/xpath_visitor.rb +8 -3
  51. data/lib/nokogiri/ffi/html/sax/parser_context.rb +3 -3
  52. data/lib/nokogiri/ffi/libxml.rb +16 -2
  53. data/lib/nokogiri/ffi/structs/common_node.rb +15 -3
  54. data/lib/nokogiri/ffi/structs/xml_document.rb +13 -4
  55. data/lib/nokogiri/ffi/structs/xml_xpath_context.rb +3 -2
  56. data/lib/nokogiri/ffi/weak_bucket.rb +40 -0
  57. data/lib/nokogiri/ffi/xml/document.rb +27 -0
  58. data/lib/nokogiri/ffi/xml/entity_decl.rb +9 -0
  59. data/lib/nokogiri/ffi/xml/node.rb +142 -61
  60. data/lib/nokogiri/ffi/xml/node_set.rb +15 -12
  61. data/lib/nokogiri/ffi/xml/reader.rb +5 -0
  62. data/lib/nokogiri/ffi/xml/schema.rb +17 -0
  63. data/lib/nokogiri/ffi/xml/syntax_error.rb +4 -4
  64. data/lib/nokogiri/ffi/xml/xpath.rb +0 -10
  65. data/lib/nokogiri/ffi/xml/xpath_context.rb +22 -9
  66. data/lib/nokogiri/ffi/xslt/stylesheet.rb +3 -0
  67. data/lib/nokogiri/html/document.rb +5 -3
  68. data/lib/nokogiri/html/document_fragment.rb +28 -7
  69. data/lib/nokogiri/version.rb +6 -2
  70. data/lib/nokogiri/version_warning.rb +6 -3
  71. data/lib/nokogiri/xml.rb +1 -1
  72. data/lib/nokogiri/xml/builder.rb +35 -22
  73. data/lib/nokogiri/xml/document.rb +44 -12
  74. data/lib/nokogiri/xml/document_fragment.rb +16 -12
  75. data/lib/nokogiri/xml/entity_decl.rb +4 -0
  76. data/lib/nokogiri/xml/node.rb +152 -95
  77. data/lib/nokogiri/xml/node_set.rb +2 -1
  78. data/lib/nokogiri/xml/sax/push_parser.rb +1 -1
  79. data/lib/nokogiri/xml/schema.rb +1 -5
  80. data/lib/nokogiri/xml/syntax_error.rb +4 -0
  81. data/lib/nokogiri/xml/text.rb +9 -0
  82. data/lib/nokogiri/xml/xpath/syntax_error.rb +3 -0
  83. data/tasks/cross_compile.rb +158 -0
  84. data/tasks/test.rb +0 -6
  85. data/test/css/test_xpath_visitor.rb +9 -0
  86. data/test/helper.rb +49 -11
  87. data/test/html/sax/test_parser.rb +11 -1
  88. data/test/html/test_document.rb +8 -0
  89. data/test/html/test_document_fragment.rb +14 -2
  90. data/test/html/test_element_description.rb +5 -1
  91. data/test/html/test_node.rb +5 -66
  92. data/test/test_reader.rb +28 -0
  93. data/test/test_xslt_transforms.rb +14 -0
  94. data/test/xml/test_builder.rb +43 -0
  95. data/test/xml/test_cdata.rb +12 -0
  96. data/test/xml/test_document.rb +74 -39
  97. data/test/xml/test_document_fragment.rb +36 -0
  98. data/test/xml/test_entity_decl.rb +37 -0
  99. data/test/xml/test_node.rb +192 -65
  100. data/test/xml/test_node_reparenting.rb +253 -236
  101. data/test/xml/test_node_set.rb +67 -0
  102. data/test/xml/test_text.rb +8 -0
  103. data/test/xml/test_xpath.rb +32 -0
  104. metadata +151 -79
  105. data/ext/nokogiri/iconv.dll +0 -0
  106. data/ext/nokogiri/libexslt.dll +0 -0
  107. data/ext/nokogiri/libxml2.dll +0 -0
  108. data/ext/nokogiri/libxslt.dll +0 -0
  109. data/ext/nokogiri/xml_xpath.c +0 -53
  110. data/ext/nokogiri/xml_xpath.h +0 -11
  111. data/ext/nokogiri/zlib1.dll +0 -0
  112. data/lib/nokogiri/xml/fragment_handler.rb +0 -79
@@ -78,18 +78,14 @@ module Nokogiri
78
78
  end
79
79
 
80
80
  def next_element
81
- sibling_ptr = cstruct[:next]
82
-
83
- while ! sibling_ptr.null?
84
- sibling_cstruct = LibXML::XmlNode.new(sibling_ptr)
85
- break if sibling_cstruct[:type] == ELEMENT_NODE
86
- sibling_ptr = sibling_cstruct[:next]
87
- end
88
-
89
- return sibling_ptr.null? ? nil : Node.wrap(sibling_ptr)
81
+ sibling_ptr = LibXML.xmlNextElementSibling cstruct
82
+ sibling_ptr.null? ? nil : Node.wrap(sibling_ptr)
90
83
  end
91
84
 
92
85
  def previous_element
86
+ #
87
+ # note that we don't use xmlPreviousElementSibling here because it's buggy pre-2.7.7.
88
+ #
93
89
  sibling_ptr = cstruct[:prev]
94
90
 
95
91
  while ! sibling_ptr.null?
@@ -102,41 +98,71 @@ module Nokogiri
102
98
  end
103
99
 
104
100
  def replace_node new_node
105
- Node.reparent_node_with(new_node, self) do |new_node_cstruct, self_cstruct|
106
- retval = LibXML.xmlReplaceNode(self_cstruct, new_node_cstruct)
107
- if retval == self_cstruct.pointer
108
- new_node_cstruct # for reparent_node_with semantics
109
- else
110
- retval
101
+ Node.reparent_node_with(self, new_node) do |pivot_struct, reparentee_struct|
102
+ retval = LibXML.xmlReplaceNode(pivot_struct, reparentee_struct)
103
+ retval = reparentee_struct if retval == pivot_struct.pointer # for reparent_node_with semantics
104
+ retval = LibXML::XmlNode.new(retval) if retval.is_a?(FFI::Pointer)
105
+ if retval[:type] == TEXT_NODE
106
+ if retval[:prev] && LibXML::XmlNode.new(retval[:prev])[:type] == TEXT_NODE
107
+ retval = LibXML::XmlNode.new(LibXML.xmlTextMerge(retval[:prev], retval))
108
+ end
109
+ if retval[:next] && LibXML::XmlNode.new(retval[:next])[:type] == TEXT_NODE
110
+ retval = LibXML::XmlNode.new(LibXML.xmlTextMerge(retval, retval[:next]))
111
+ end
111
112
  end
113
+ retval
112
114
  end
113
- self
114
115
  end
115
116
 
116
117
  def children
117
118
  return NodeSet.new(nil) if cstruct[:children].null?
118
119
  child = Node.wrap(cstruct[:children])
119
120
 
120
- set = NodeSet.new child.document
121
- set_ptr = LibXML.xmlXPathNodeSetCreate(child.cstruct)
122
-
123
- set.cstruct = LibXML::XmlNodeSet.new(set_ptr)
121
+ set = NodeSet.wrap(LibXML.xmlXPathNodeSetCreate(child.cstruct), self.document)
124
122
  return set unless child
125
123
 
126
124
  child_ptr = child.cstruct[:next]
127
125
  while ! child_ptr.null?
128
126
  child = Node.wrap(child_ptr)
129
- LibXML.xmlXPathNodeSetAdd(set.cstruct, child.cstruct)
127
+ LibXML.xmlXPathNodeSetAddUnique(set.cstruct, child.cstruct)
130
128
  child_ptr = child.cstruct[:next]
131
129
  end
132
130
 
133
131
  return set
134
132
  end
135
133
 
134
+ def element_children
135
+ child = LibXML.xmlFirstElementChild(cstruct)
136
+ return NodeSet.new(nil) if child.null?
137
+ child = Node.wrap(child)
138
+
139
+ set = NodeSet.wrap(LibXML.xmlXPathNodeSetCreate(child.cstruct), self.document)
140
+ return set unless child
141
+
142
+ next_sibling = LibXML.xmlNextElementSibling(child.cstruct)
143
+ while ! next_sibling.null?
144
+ child = Node.wrap(next_sibling)
145
+ LibXML.xmlXPathNodeSetAddUnique(set.cstruct, child.cstruct)
146
+ next_sibling = LibXML.xmlNextElementSibling(child.cstruct)
147
+ end
148
+
149
+ return set
150
+ end
151
+
136
152
  def child
137
153
  (val = cstruct[:children]).null? ? nil : Node.wrap(val)
138
154
  end
139
155
 
156
+ def first_element_child
157
+ element_child = LibXML.xmlFirstElementChild(cstruct)
158
+ element_child.null? ? nil : Node.wrap(element_child)
159
+ end
160
+
161
+ def last_element_child
162
+ element_child = LibXML.xmlLastElementChild(cstruct)
163
+ element_child.null? ? nil : Node.wrap(element_child)
164
+ end
165
+
140
166
  def key?(attribute)
141
167
  ! (prop = LibXML.xmlHasProp(cstruct, attribute.to_s)).null?
142
168
  end
@@ -162,7 +188,7 @@ module Nokogiri
162
188
  end
163
189
 
164
190
  def set_namespace(namespace)
165
- LibXML.xmlSetNs(cstruct, namespace.cstruct)
191
+ LibXML.xmlSetNs(cstruct, namespace ? namespace.cstruct : nil)
166
192
  self
167
193
  end
168
194
 
@@ -197,11 +223,32 @@ module Nokogiri
197
223
  list
198
224
  end
199
225
 
226
+ def namespace_scopes
227
+ ns_list = LibXML.xmlGetNsList(self.cstruct[:doc], self.cstruct)
228
+ return [] if ns_list.null?
229
+
230
+ list = []
231
+ until (ns_ptr = ns_list.get_pointer(LibXML.pointer_offset(list.length))).null?
232
+ list << Namespace.wrap(cstruct.document, ns_ptr)
233
+ end
234
+
235
+ LibXML.xmlFree(ns_list)
236
+ list
237
+ end
238
+
200
239
  def node_type
201
240
  cstruct[:type]
202
241
  end
203
242
 
204
243
  def native_content=(content)
244
+ child_ptr = cstruct[:children]
245
+ while ! child_ptr.null?
246
+ child = Node.wrap(child_ptr)
247
+ next_ptr = child.cstruct[:next]
248
+ LibXML.xmlUnlinkNode(child.cstruct)
249
+ cstruct.keep_reference_from_document!
250
+ child_ptr = next_ptr
251
+ end
205
252
  LibXML.xmlNodeSetContent(cstruct, content)
206
253
  content
207
254
  end
@@ -215,8 +262,8 @@ module Nokogiri
215
262
  end
216
263
 
217
264
  def add_child_node child
218
- Node.reparent_node_with(child, self) do |child_cstruct, my_cstruct|
219
- LibXML.xmlAddChild(my_cstruct, child_cstruct)
265
+ Node.reparent_node_with(self, child) do |pivot_struct, reparentee_struct|
266
+ LibXML.xmlAddChild(pivot_struct, reparentee_struct)
220
267
  end
221
268
  end
222
269
 
@@ -241,14 +288,14 @@ module Nokogiri
241
288
  end
242
289
 
243
290
  def add_next_sibling_node next_sibling
244
- Node.reparent_node_with(next_sibling, self) do |sibling_cstruct, my_cstruct|
245
- LibXML.xmlAddNextSibling(my_cstruct, sibling_cstruct)
291
+ Node.reparent_node_with(self, next_sibling) do |pivot_struct, reparentee_struct|
292
+ LibXML.xmlAddNextSibling(pivot_struct, reparentee_struct)
246
293
  end
247
294
  end
248
295
 
249
296
  def add_previous_sibling_node prev_sibling
250
- Node.reparent_node_with(prev_sibling, self) do |sibling_cstruct, my_cstruct|
251
- LibXML.xmlAddPrevSibling(my_cstruct, sibling_cstruct)
297
+ Node.reparent_node_with(self, prev_sibling) do |pivot_struct, reparentee_struct|
298
+ LibXML.xmlAddPrevSibling(pivot_struct, reparentee_struct)
252
299
  end
253
300
  end
254
301
 
@@ -359,6 +406,29 @@ module Nokogiri
359
406
  cstruct.document.ruby_doc
360
407
  end
361
408
 
409
+ def in_context(string, options)
410
+ raise RuntimeError, "no contextual parsing on unlinked nodes" if parent.nil?
411
+
412
+ @errors = []
413
+ LibXML.xmlSetStructuredErrorFunc(nil, SyntaxError.error_array_pusher(@errors))
414
+ LibXML.htmlHandleOmittedElem(0)
415
+
416
+ list_memory = FFI::MemoryPointer.new :pointer
417
+ LibXML.xmlParseInNodeContext(cstruct, string, string.length, options, list_memory)
418
+
419
+ LibXML.htmlHandleOmittedElem(1)
420
+ LibXML.xmlSetStructuredErrorFunc(nil, nil)
421
+
422
+ set = NodeSet.wrap(LibXML.xmlXPathNodeSetCreate(nil), document)
423
+ list_ptr = list_memory.get_pointer(0)
424
+ while ! list_ptr.null?
425
+ list = Node.wrap(list_ptr)
426
+ LibXML.xmlXPathNodeSetAddUnique(set.cstruct, list.cstruct)
427
+ list_ptr = list.cstruct[:next]
428
+ end
429
+ set
430
+ end
431
+
362
432
  class << self
363
433
  def node_properties(cstruct)
364
434
  attr = []
@@ -374,38 +444,31 @@ module Nokogiri
374
444
 
375
445
  private
376
446
 
377
- def self.reparent_node_with(node, other, &block)
378
- raise(ArgumentError, "node must be a Nokogiri::XML::Node") unless node.is_a?(Nokogiri::XML::Node)
379
- raise(ArgumentError, "cannot reparent a document node") if node.node_type == DOCUMENT_NODE || node.node_type == HTML_DOCUMENT_NODE
447
+ def self.reparent_node_with(pivot, reparentee, &block)
448
+ raise(ArgumentError, "node must be a Nokogiri::XML::Node") unless reparentee.is_a?(Nokogiri::XML::Node)
449
+ raise(ArgumentError, "cannot reparent a document node") if reparentee.node_type == DOCUMENT_NODE || reparentee.node_type == HTML_DOCUMENT_NODE
380
450
 
381
- if node.type == TEXT_NODE
382
- node.cstruct.keep_reference_from_document!
383
- node.cstruct = LibXML::XmlNode.new(LibXML.xmlDocCopyNode(node.cstruct, other.cstruct.document, 1))
451
+ pivot_struct = pivot.cstruct
452
+ reparentee_struct = reparentee.cstruct
453
+
454
+ LibXML.xmlUnlinkNode(reparentee_struct)
455
+
456
+ if reparentee_struct[:doc] != pivot_struct[:doc] || reparentee_struct[:type] == TEXT_NODE
457
+ reparentee_struct.keep_reference_from_document!
458
+ reparentee_struct = LibXML.xmlDocCopyNode(reparentee_struct, pivot_struct.document, 1)
459
+ raise(RuntimeError, "Could not reparent node (xmlDocCopyNode)") unless reparentee_struct
460
+ reparentee_struct = LibXML::XmlNode.new(reparentee_struct)
384
461
  end
385
462
 
386
- if node.cstruct[:doc] == other.cstruct[:doc]
387
- LibXML.xmlUnlinkNode(node.cstruct)
388
- if node.type == TEXT_NODE && other.type == TEXT_NODE && Nokogiri.is_2_6_16?
389
- other.cstruct.pointer.put_pointer(other.cstruct.offset_of(:content), LibXML.xmlStrdup(other.cstruct[:content]))
390
- end
391
- reparented_struct = block.call(node.cstruct, other.cstruct)
392
- raise(RuntimeError, "Could not reparent node (1)") unless reparented_struct
393
- else
394
- duped_node = LibXML.xmlDocCopyNode(node.cstruct, other.cstruct.document, 1)
395
- raise(RuntimeError, "Could not reparent node (xmlDocCopyNode)") unless duped_node
396
- reparented_struct = block.call(duped_node, other.cstruct)
397
- raise(RuntimeError, "Could not reparent node (2)") unless reparented_struct
398
- LibXML.xmlUnlinkNode(node.cstruct)
399
- node.cstruct.keep_reference_from_document!
463
+ if reparentee_struct[:type] == TEXT_NODE && pivot_struct[:type] == TEXT_NODE && Nokogiri.is_2_6_16?
464
+ pivot_struct.pointer.put_pointer(pivot_struct.offset_of(:content), LibXML.xmlStrdup(pivot_struct[:content]))
400
465
  end
401
466
 
402
- reparented_struct = LibXML::XmlNode.new(reparented_struct) if reparented_struct.is_a?(FFI::Pointer)
467
+ reparented_struct = block.call(pivot_struct, reparentee_struct)
468
+ raise(RuntimeError, "Could not reparent node") unless reparented_struct
403
469
 
404
- # the child was a text node that was coalesced. we need to have the object
405
- # point at SOMETHING, or we'll totally bomb out.
406
- if reparented_struct != node.cstruct
407
- node.cstruct = reparented_struct
408
- end
470
+ reparented_struct = LibXML::XmlNode.new(reparented_struct) if reparented_struct.is_a?(FFI::Pointer)
471
+ reparentee.cstruct = reparented_struct
409
472
 
410
473
  relink_namespace reparented_struct
411
474
 
@@ -424,12 +487,30 @@ module Nokogiri
424
487
 
425
488
  # Search our parents for an existing definition
426
489
  if ! reparented_struct[:nsDef].null?
427
- ns = LibXML.xmlSearchNsByHref(
428
- reparented_struct[:doc],
429
- reparented_struct[:parent],
430
- LibXML::XmlNs.new(reparented_struct[:nsDef])[:href]
431
- )
432
- reparented_struct[:nsDef] = nil unless ns.null?
490
+ curr = reparented_struct[:nsDef]
491
+ prev = nil
492
+
493
+ while (! curr.null?)
494
+ curr_ns = LibXML::XmlNs.new(curr)
495
+ ns = LibXML.xmlSearchNsByHref(
496
+ reparented_struct[:doc],
497
+ reparented_struct[:parent],
498
+ curr_ns[:href]
499
+ )
500
+ # If we find the namespace is already declared, remove it from this
501
+ # definition list.
502
+ if (! ns.null? && ns != curr)
503
+ if prev
504
+ prev[:next] = curr_ns[:next]
505
+ else
506
+ reparented_struct[:nsDef] = curr_ns[:next]
507
+ end
508
+ curr_ns.keep_reference_from!(reparented_struct.document)
509
+ else
510
+ prev = curr_ns
511
+ end
512
+ curr = curr_ns[:next]
513
+ end
433
514
  end
434
515
 
435
516
  # Only walk all children if there actually is a namespace we need to reparent.
@@ -439,7 +520,7 @@ module Nokogiri
439
520
  # their namespaces are reparented as well.
440
521
  child_ptr = reparented_struct[:children]
441
522
  while ! child_ptr.null?
442
- child_struct = LibXML::XmlNode.new(child_ptr)
523
+ child_struct = LibXML::XmlNode.new(child_ptr)
443
524
  relink_namespace child_struct
444
525
  child_ptr = child_struct[:next]
445
526
  end
@@ -6,7 +6,7 @@ module Nokogiri
6
6
 
7
7
  def dup # :nodoc:
8
8
  dup = LibXML.xmlXPathNodeSetMerge(nil, self.cstruct)
9
- NodeSet.wrap(dup)
9
+ NodeSet.wrap(dup, self.document)
10
10
  end
11
11
 
12
12
  def length # :nodoc:
@@ -24,9 +24,7 @@ module Nokogiri
24
24
  new_set_ptr = LibXML::xmlXPathNodeSetMerge(nil, self.cstruct)
25
25
  new_set_ptr = LibXML::xmlXPathNodeSetMerge(new_set_ptr, node_set.cstruct)
26
26
 
27
- new_set = NodeSet.wrap(new_set_ptr)
28
- new_set.document = document
29
- new_set
27
+ NodeSet.wrap(new_set_ptr, self.document)
30
28
  end
31
29
 
32
30
  def -(node_set) # :nodoc:
@@ -37,7 +35,7 @@ module Nokogiri
37
35
  node_set.cstruct[:nodeNr].times do |j|
38
36
  LibXML.xmlXPathNodeSetDel(new_set_ptr, other_nodetab[j])
39
37
  end
40
- NodeSet.wrap(new_set_ptr)
38
+ NodeSet.wrap(new_set_ptr, self.document)
41
39
  end
42
40
 
43
41
  def delete(node) # :nodoc:
@@ -69,7 +67,7 @@ module Nokogiri
69
67
  def &(node_set) # :nodoc:
70
68
  raise(ArgumentError, "node_set must be a Nokogiri::XML::NodeSet") unless node_set.is_a?(XML::NodeSet)
71
69
  new_set_ptr = LibXML.xmlXPathIntersection(cstruct, node_set.cstruct)
72
- NodeSet.wrap(new_set_ptr)
70
+ NodeSet.wrap(new_set_ptr, self.document)
73
71
  end
74
72
 
75
73
  def include?(node) # :nodoc:
@@ -103,21 +101,25 @@ module Nokogiri
103
101
  end
104
102
 
105
103
  def self.new document, list = [] # :nodoc:
106
- set = NodeSet.wrap(LibXML.xmlXPathNodeSetCreate(nil))
104
+ set = NodeSet.wrap(LibXML.xmlXPathNodeSetCreate(nil), document)
107
105
  set.document = document
108
106
  list.each { |x| set << x }
109
107
  yield set if block_given?
110
108
  set
111
109
  end
112
110
 
113
- private
114
-
115
- def self.wrap(ptr) # :nodoc:
111
+ def self.wrap(ptr, document) # :nodoc:
116
112
  set = allocate
117
113
  set.cstruct = LibXML::XmlNodeSet.new(ptr)
114
+ if document
115
+ set.document = document
116
+ document.decorate(set)
117
+ end
118
118
  set
119
119
  end
120
120
 
121
+ private
122
+
121
123
  def index_at(number) # :nodoc:
122
124
  return nil if (number >= cstruct[:nodeNr] || number.abs > cstruct[:nodeNr])
123
125
  number = number + cstruct[:nodeNr] if number < 0
@@ -133,10 +135,11 @@ module Nokogiri
133
135
  def subseq(beg, len) # :nodoc:
134
136
  return nil if beg > cstruct[:nodeNr]
135
137
  return nil if beg < 0 || len < 0
138
+ len = cstruct[:nodeNr] - beg if beg + len > cstruct[:nodeNr]
136
139
 
137
- set = NodeSet.wrap(LibXML.xmlXPathNodeSetCreate(nil))
140
+ set = NodeSet.wrap(LibXML.xmlXPathNodeSetCreate(nil), self.document)
138
141
  beg.upto(beg+len-1) do |j|
139
- LibXML.xmlXPathNodeSetAdd(set.cstruct, cstruct.nodeAt(j));
142
+ LibXML.xmlXPathNodeSetAddUnique(set.cstruct, cstruct.nodeAt(j));
140
143
  end
141
144
  set
142
145
  end
@@ -127,6 +127,11 @@ module Nokogiri
127
127
  val.null? ? nil : val.read_string
128
128
  end
129
129
 
130
+ def base_uri
131
+ val = LibXML.xmlTextReaderConstBaseUri(cstruct)
132
+ val.null? ? nil : val.read_string
133
+ end
134
+
130
135
  def state
131
136
  LibXML.xmlTextReaderReadState(cstruct)
132
137
  end
@@ -22,6 +22,23 @@ module Nokogiri
22
22
  end
23
23
  private :validate_document
24
24
 
25
+ def validate_file filename
26
+ errors = []
27
+
28
+ ctx = LibXML.xmlSchemaNewValidCtxt(cstruct)
29
+ raise RuntimeError.new("Could not create a validation context") if ctx.null?
30
+
31
+ LibXML.xmlSchemaSetValidStructuredErrors(ctx,
32
+ SyntaxError.error_array_pusher(errors), nil) unless Nokogiri.is_2_6_16?
33
+
34
+ LibXML.xmlSchemaValidateFile(ctx, filename, 0)
35
+
36
+ LibXML.xmlSchemaFreeValidCtxt(ctx)
37
+
38
+ errors
39
+ end
40
+ private :validate_document
41
+
25
42
  def self.read_memory content
26
43
  content_copy = FFI::MemoryPointer.from_string(content)
27
44
  ctx = LibXML.xmlSchemaNewMemParserCtxt(content_copy, content.length)
@@ -20,7 +20,7 @@ module Nokogiri
20
20
 
21
21
  def message
22
22
  val = cstruct[:message]
23
- val.null? ? nil : val.read_string
23
+ val.null? ? nil : val.read_string.chomp
24
24
  end
25
25
  undef_method :inspect
26
26
  alias_method :inspect, :message
@@ -54,15 +54,15 @@ module Nokogiri
54
54
  end
55
55
 
56
56
  def str1
57
- cstruct[:str1].null? ? nil : cstruct[:str1]
57
+ cstruct[:str1]
58
58
  end
59
59
 
60
60
  def str2
61
- cstruct[:str].null? ? nil : cstruct[:str]
61
+ cstruct[:str]
62
62
  end
63
63
 
64
64
  def str3
65
- cstruct[:str3].null? ? nil : cstruct[:str3]
65
+ cstruct[:str3]
66
66
  end
67
67
 
68
68
  def int1