nokogiri 1.12.5 → 1.13.0
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.
- checksums.yaml +4 -4
- data/Gemfile +2 -0
- data/README.md +9 -7
- data/bin/nokogiri +63 -50
- data/dependencies.yml +5 -6
- data/ext/nokogiri/extconf.rb +47 -35
- data/ext/nokogiri/xml_document.c +35 -35
- data/ext/nokogiri/xml_document_fragment.c +0 -2
- data/ext/nokogiri/xml_dtd.c +2 -2
- data/ext/nokogiri/xml_encoding_handler.c +25 -11
- data/ext/nokogiri/xml_node.c +638 -333
- data/ext/nokogiri/xml_reader.c +37 -11
- data/ext/nokogiri/xml_xpath_context.c +72 -49
- data/gumbo-parser/src/parser.c +0 -11
- data/lib/nokogiri/class_resolver.rb +67 -0
- data/lib/nokogiri/css/node.rb +9 -8
- data/lib/nokogiri/css/parser.rb +11 -3
- data/lib/nokogiri/css/parser.y +10 -2
- data/lib/nokogiri/css/parser_extras.rb +20 -20
- data/lib/nokogiri/css/syntax_error.rb +1 -0
- data/lib/nokogiri/css/tokenizer.rb +2 -1
- data/lib/nokogiri/css/tokenizer.rex +2 -1
- data/lib/nokogiri/css/xpath_visitor.rb +174 -75
- data/lib/nokogiri/css.rb +38 -6
- data/lib/nokogiri/decorators/slop.rb +8 -7
- data/lib/nokogiri/extension.rb +1 -1
- data/lib/nokogiri/gumbo.rb +1 -0
- data/lib/nokogiri/html.rb +16 -10
- data/lib/nokogiri/html4/builder.rb +1 -0
- data/lib/nokogiri/html4/document.rb +84 -75
- data/lib/nokogiri/html4/document_fragment.rb +11 -7
- data/lib/nokogiri/html4/element_description.rb +1 -0
- data/lib/nokogiri/html4/element_description_defaults.rb +426 -520
- data/lib/nokogiri/html4/entity_lookup.rb +2 -1
- data/lib/nokogiri/html4/sax/parser.rb +2 -1
- data/lib/nokogiri/html4/sax/parser_context.rb +1 -0
- data/lib/nokogiri/html4/sax/push_parser.rb +7 -7
- data/lib/nokogiri/html4.rb +11 -5
- data/lib/nokogiri/html5/document.rb +24 -10
- data/lib/nokogiri/html5/document_fragment.rb +5 -2
- data/lib/nokogiri/html5/node.rb +6 -3
- data/lib/nokogiri/html5.rb +68 -64
- data/lib/nokogiri/jruby/dependencies.rb +10 -9
- data/lib/nokogiri/syntax_error.rb +1 -0
- data/lib/nokogiri/version/constant.rb +2 -1
- data/lib/nokogiri/version/info.rb +19 -13
- data/lib/nokogiri/version.rb +1 -0
- data/lib/nokogiri/xml/attr.rb +5 -3
- data/lib/nokogiri/xml/attribute_decl.rb +2 -1
- data/lib/nokogiri/xml/builder.rb +32 -32
- data/lib/nokogiri/xml/cdata.rb +2 -1
- data/lib/nokogiri/xml/character_data.rb +1 -0
- data/lib/nokogiri/xml/document.rb +139 -103
- data/lib/nokogiri/xml/document_fragment.rb +41 -38
- data/lib/nokogiri/xml/dtd.rb +3 -2
- data/lib/nokogiri/xml/element_content.rb +1 -0
- data/lib/nokogiri/xml/element_decl.rb +2 -1
- data/lib/nokogiri/xml/entity_decl.rb +3 -2
- data/lib/nokogiri/xml/entity_reference.rb +1 -0
- data/lib/nokogiri/xml/namespace.rb +2 -0
- data/lib/nokogiri/xml/node/save_options.rb +6 -3
- data/lib/nokogiri/xml/node.rb +512 -348
- data/lib/nokogiri/xml/node_set.rb +46 -54
- data/lib/nokogiri/xml/notation.rb +12 -0
- data/lib/nokogiri/xml/parse_options.rb +11 -7
- data/lib/nokogiri/xml/pp/character_data.rb +8 -6
- data/lib/nokogiri/xml/pp/node.rb +24 -26
- data/lib/nokogiri/xml/pp.rb +1 -0
- data/lib/nokogiri/xml/processing_instruction.rb +2 -1
- data/lib/nokogiri/xml/reader.rb +17 -19
- data/lib/nokogiri/xml/relax_ng.rb +1 -0
- data/lib/nokogiri/xml/sax/document.rb +20 -19
- data/lib/nokogiri/xml/sax/parser.rb +36 -34
- data/lib/nokogiri/xml/sax/parser_context.rb +7 -3
- data/lib/nokogiri/xml/sax/push_parser.rb +5 -5
- data/lib/nokogiri/xml/sax.rb +1 -0
- data/lib/nokogiri/xml/schema.rb +7 -6
- data/lib/nokogiri/xml/searchable.rb +42 -22
- data/lib/nokogiri/xml/syntax_error.rb +4 -4
- data/lib/nokogiri/xml/text.rb +1 -0
- data/lib/nokogiri/xml/xpath/syntax_error.rb +2 -1
- data/lib/nokogiri/xml/xpath.rb +12 -0
- data/lib/nokogiri/xml/xpath_context.rb +2 -3
- data/lib/nokogiri/xml.rb +3 -3
- data/lib/nokogiri/xslt/stylesheet.rb +1 -0
- data/lib/nokogiri/xslt.rb +3 -2
- data/lib/nokogiri.rb +19 -16
- data/lib/xsd/xmlparser/nokogiri.rb +25 -24
- data/patches/libxml2/0008-htmlParseComment-handle-abruptly-closed-comments.patch +61 -0
- data/patches/libxml2/0009-allow-wildcard-namespaces.patch +77 -0
- metadata +101 -27
data/lib/nokogiri/xml/attr.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Nokogiri
|
3
4
|
module XML
|
4
5
|
class Attr < Node
|
5
|
-
|
6
|
-
|
7
|
-
|
6
|
+
alias_method :value, :content
|
7
|
+
alias_method :to_s, :content
|
8
|
+
alias_method :content=, :value=
|
8
9
|
|
9
10
|
private
|
11
|
+
|
10
12
|
def inspect_attributes
|
11
13
|
[:name, :namespace, :value]
|
12
14
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Nokogiri
|
3
4
|
module XML
|
4
5
|
###
|
@@ -12,7 +13,7 @@ module Nokogiri
|
|
12
13
|
undef_method :line if method_defined?(:line)
|
13
14
|
|
14
15
|
def inspect
|
15
|
-
"#<#{self.class.name}:#{
|
16
|
+
"#<#{self.class.name}:#{format("0x%x", object_id)} #{to_s.inspect}>"
|
16
17
|
end
|
17
18
|
end
|
18
19
|
end
|
data/lib/nokogiri/xml/builder.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Nokogiri
|
3
4
|
module XML
|
4
5
|
###
|
@@ -261,7 +262,9 @@ module Nokogiri
|
|
261
262
|
# </root>
|
262
263
|
#
|
263
264
|
class Builder
|
264
|
-
|
265
|
+
include Nokogiri::ClassResolver
|
266
|
+
|
267
|
+
DEFAULT_DOCUMENT_OPTIONS = { namespace_inheritance: true }
|
265
268
|
|
266
269
|
# The current Document object being built
|
267
270
|
attr_accessor :doc
|
@@ -306,13 +309,7 @@ module Nokogiri
|
|
306
309
|
@doc = root.document
|
307
310
|
@parent = root
|
308
311
|
else
|
309
|
-
|
310
|
-
klass = begin
|
311
|
-
Object.const_get(klassname)
|
312
|
-
rescue NameError
|
313
|
-
Nokogiri::XML::Document
|
314
|
-
end
|
315
|
-
@parent = @doc = klass.new
|
312
|
+
@parent = @doc = related_class("Document").new
|
316
313
|
end
|
317
314
|
|
318
315
|
@context = nil
|
@@ -324,7 +321,7 @@ module Nokogiri
|
|
324
321
|
@doc.send(:"#{k}=", v)
|
325
322
|
end
|
326
323
|
|
327
|
-
return unless
|
324
|
+
return unless block
|
328
325
|
|
329
326
|
@arity = block.arity
|
330
327
|
if @arity <= 0
|
@@ -340,19 +337,19 @@ module Nokogiri
|
|
340
337
|
###
|
341
338
|
# Create a Text Node with content of +string+
|
342
339
|
def text(string)
|
343
|
-
insert
|
340
|
+
insert(@doc.create_text_node(string))
|
344
341
|
end
|
345
342
|
|
346
343
|
###
|
347
344
|
# Create a CDATA Node with content of +string+
|
348
345
|
def cdata(string)
|
349
|
-
insert
|
346
|
+
insert(doc.create_cdata(string))
|
350
347
|
end
|
351
348
|
|
352
349
|
###
|
353
350
|
# Create a Comment Node with content of +string+
|
354
351
|
def comment(string)
|
355
|
-
insert
|
352
|
+
insert(doc.create_comment(string))
|
356
353
|
end
|
357
354
|
|
358
355
|
###
|
@@ -370,8 +367,8 @@ module Nokogiri
|
|
370
367
|
return self if @ns
|
371
368
|
end
|
372
369
|
|
373
|
-
@ns = { :
|
374
|
-
|
370
|
+
@ns = { pending: ns.to_s }
|
371
|
+
self
|
375
372
|
end
|
376
373
|
|
377
374
|
###
|
@@ -379,7 +376,7 @@ module Nokogiri
|
|
379
376
|
def to_xml(*args)
|
380
377
|
if Nokogiri.jruby?
|
381
378
|
options = args.first.is_a?(Hash) ? args.shift : {}
|
382
|
-
|
379
|
+
unless options[:save_with]
|
383
380
|
options[:save_with] = Node::SaveOptions::AS_BUILDER
|
384
381
|
end
|
385
382
|
args.insert(0, options)
|
@@ -394,18 +391,18 @@ module Nokogiri
|
|
394
391
|
end
|
395
392
|
|
396
393
|
def method_missing(method, *args, &block) # :nodoc:
|
397
|
-
if @context
|
394
|
+
if @context&.respond_to?(method)
|
398
395
|
@context.send(method, *args, &block)
|
399
396
|
else
|
400
|
-
node = @doc.create_element(method.to_s.sub(/[_!]$/, ""), *args)
|
397
|
+
node = @doc.create_element(method.to_s.sub(/[_!]$/, ""), *args) do |n|
|
401
398
|
# Set up the namespace
|
402
|
-
if @ns.is_a?
|
399
|
+
if @ns.is_a?(Nokogiri::XML::Namespace)
|
403
400
|
n.namespace = @ns
|
404
401
|
@ns = nil
|
405
402
|
end
|
406
|
-
|
403
|
+
end
|
407
404
|
|
408
|
-
if @ns.is_a?
|
405
|
+
if @ns.is_a?(Hash)
|
409
406
|
node.namespace = node.namespace_definitions.find { |x| x.prefix == @ns[:pending] }
|
410
407
|
if node.namespace.nil?
|
411
408
|
raise ArgumentError, "Namespace #{@ns[:pending]} has not been defined"
|
@@ -423,16 +420,19 @@ module Nokogiri
|
|
423
420
|
# Insert +node+ as a child of the current Node
|
424
421
|
def insert(node, &block)
|
425
422
|
node = @parent.add_child(node)
|
426
|
-
if
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
423
|
+
if block
|
424
|
+
begin
|
425
|
+
old_parent = @parent
|
426
|
+
@parent = node
|
427
|
+
@arity ||= block.arity
|
428
|
+
if @arity <= 0
|
429
|
+
instance_eval(&block)
|
430
|
+
else
|
431
|
+
yield(self)
|
432
|
+
end
|
433
|
+
ensure
|
434
|
+
@parent = old_parent
|
434
435
|
end
|
435
|
-
@parent = old_parent
|
436
436
|
end
|
437
437
|
NodeBuilder.new(node, self)
|
438
438
|
end
|
@@ -455,10 +455,10 @@ module Nokogiri
|
|
455
455
|
opts = args.last.is_a?(Hash) ? args.pop : {}
|
456
456
|
case method.to_s
|
457
457
|
when /^(.*)!$/
|
458
|
-
@node["id"] =
|
458
|
+
@node["id"] = Regexp.last_match(1)
|
459
459
|
@node.content = args.first if args.first
|
460
460
|
when /^(.*)=/
|
461
|
-
@node[
|
461
|
+
@node[Regexp.last_match(1)] = args.first
|
462
462
|
else
|
463
463
|
@node["class"] =
|
464
464
|
((@node["class"] || "").split(/\s/) + [method.to_s]).join(" ")
|
@@ -470,7 +470,7 @@ module Nokogiri
|
|
470
470
|
@node[k.to_s] = ((@node[k.to_s] || "").split(/\s/) + [v]).join(" ")
|
471
471
|
end
|
472
472
|
|
473
|
-
if
|
473
|
+
if block
|
474
474
|
old_parent = @doc_builder.parent
|
475
475
|
@doc_builder.parent = @node
|
476
476
|
value = @doc_builder.instance_eval(&block)
|
data/lib/nokogiri/xml/cdata.rb
CHANGED
@@ -1,18 +1,16 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require
|
4
|
+
require "pathname"
|
5
5
|
|
6
6
|
module Nokogiri
|
7
7
|
module XML
|
8
|
-
|
9
|
-
# Nokogiri::XML::Document
|
10
|
-
#
|
11
|
-
# See Nokogiri::XML::Document.parse() for more information on parsing.
|
8
|
+
# Nokogiri::XML::Document is the main entry point for dealing with XML documents. The Document
|
9
|
+
# is created by parsing an XML document. See Nokogiri::XML::Document.parse for more information
|
10
|
+
# on parsing.
|
12
11
|
#
|
13
12
|
# For searching a Document, see Nokogiri::XML::Searchable#css and
|
14
13
|
# Nokogiri::XML::Searchable#xpath
|
15
|
-
#
|
16
14
|
class Document < Nokogiri::XML::Node
|
17
15
|
# See http://www.w3.org/TR/REC-xml-names/#ns-decl for more details. Note that we're not
|
18
16
|
# attempting to handle unicode characters partly because libxml2 doesn't handle unicode
|
@@ -47,76 +45,86 @@ module Nokogiri
|
|
47
45
|
#
|
48
46
|
# Nokogiri.XML() is a convenience method which will call this method.
|
49
47
|
#
|
50
|
-
def self.parse
|
48
|
+
def self.parse(string_or_io, url = nil, encoding = nil, options = ParseOptions::DEFAULT_XML)
|
51
49
|
options = Nokogiri::XML::ParseOptions.new(options) if Integer === options
|
52
|
-
|
53
50
|
yield options if block_given?
|
54
51
|
|
55
52
|
url ||= string_or_io.respond_to?(:path) ? string_or_io.path : nil
|
56
53
|
|
57
54
|
if empty_doc?(string_or_io)
|
58
55
|
if options.strict?
|
59
|
-
raise Nokogiri::XML::SyntaxError
|
56
|
+
raise Nokogiri::XML::SyntaxError, "Empty document"
|
60
57
|
else
|
61
58
|
return encoding ? new.tap { |i| i.encoding = encoding } : new
|
62
59
|
end
|
63
60
|
end
|
64
61
|
|
65
62
|
doc = if string_or_io.respond_to?(:read)
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
63
|
+
if string_or_io.is_a?(Pathname)
|
64
|
+
# resolve the Pathname to the file and open it as an IO object, see #2110
|
65
|
+
string_or_io = string_or_io.expand_path.open
|
66
|
+
url ||= string_or_io.path
|
67
|
+
end
|
71
68
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
69
|
+
read_io(string_or_io, url, encoding, options.to_i)
|
70
|
+
else
|
71
|
+
# read_memory pukes on empty docs
|
72
|
+
read_memory(string_or_io, url, encoding, options.to_i)
|
73
|
+
end
|
77
74
|
|
78
75
|
# do xinclude processing
|
79
76
|
doc.do_xinclude(options) if options.xinclude?
|
80
77
|
|
81
|
-
|
78
|
+
doc
|
82
79
|
end
|
83
80
|
|
84
81
|
##
|
85
|
-
#
|
86
|
-
#
|
82
|
+
# :singleton-method: wrap
|
83
|
+
# :call-seq: wrap(java_document) → Nokogiri::XML::Document
|
84
|
+
#
|
85
|
+
# ⚠ This method is only available when running JRuby.
|
87
86
|
#
|
88
|
-
# Create a
|
87
|
+
# Create a Document using an existing Java DOM document object.
|
89
88
|
#
|
90
|
-
# The returned
|
89
|
+
# The returned Document shares the same underlying data structure as the Java object, so
|
91
90
|
# changes in one are reflected in the other.
|
92
91
|
#
|
93
|
-
#
|
94
|
-
#
|
95
|
-
#
|
96
|
-
#
|
97
|
-
#
|
92
|
+
# [Parameters]
|
93
|
+
# - `java_document` (Java::OrgW3cDom::Document)
|
94
|
+
# (The class `Java::OrgW3cDom::Document` is also accessible as `org.w3c.dom.Document`.)
|
95
|
+
#
|
96
|
+
# [Returns] Nokogiri::XML::Document
|
97
|
+
#
|
98
|
+
# See also \#to_java
|
98
99
|
|
99
|
-
|
100
|
-
#
|
100
|
+
# :method: to_java
|
101
|
+
# :call-seq: to_java() → Java::OrgW3cDom::Document
|
101
102
|
#
|
102
|
-
#
|
103
|
+
# ⚠ This method is only available when running JRuby.
|
103
104
|
#
|
104
|
-
#
|
105
|
+
# Returns the underlying Java DOM document object for this document.
|
106
|
+
#
|
107
|
+
# The returned Java object shares the same underlying data structure as this document, so
|
105
108
|
# changes in one are reflected in the other.
|
106
109
|
#
|
107
|
-
#
|
108
|
-
#
|
109
|
-
#
|
110
|
-
#
|
111
|
-
|
110
|
+
# [Returns]
|
111
|
+
# Java::OrgW3cDom::Document
|
112
|
+
# (The class `Java::OrgW3cDom::Document` is also accessible as `org.w3c.dom.Document`.)
|
113
|
+
#
|
114
|
+
# See also Document.wrap
|
112
115
|
|
113
|
-
#
|
116
|
+
# The errors found while parsing a document.
|
117
|
+
#
|
118
|
+
# [Returns] Array<Nokogiri::XML::SyntaxError>
|
114
119
|
attr_accessor :errors
|
115
120
|
|
116
|
-
# When true
|
117
|
-
# namespace (if one exists). Defaults to
|
121
|
+
# When `true`, reparented elements without a namespace will inherit their new parent's
|
122
|
+
# namespace (if one exists). Defaults to `false`.
|
123
|
+
#
|
124
|
+
# [Returns] Boolean
|
125
|
+
#
|
126
|
+
# *Example:* Default behavior of namespace inheritance
|
118
127
|
#
|
119
|
-
# @example Default behavior of namespace inheritance
|
120
128
|
# xml = <<~EOF
|
121
129
|
# <root xmlns:foo="http://nokogiri.org/default_ns/test/foo">
|
122
130
|
# <foo:parent>
|
@@ -134,7 +142,8 @@ module Nokogiri
|
|
134
142
|
# # </foo:parent>
|
135
143
|
# # </root>
|
136
144
|
#
|
137
|
-
#
|
145
|
+
# *Example:* Setting namespace inheritance to `true`
|
146
|
+
#
|
138
147
|
# xml = <<~EOF
|
139
148
|
# <root xmlns:foo="http://nokogiri.org/default_ns/test/foo">
|
140
149
|
# <foo:parent>
|
@@ -153,49 +162,61 @@ module Nokogiri
|
|
153
162
|
# # </foo:parent>
|
154
163
|
# # </root>
|
155
164
|
#
|
156
|
-
#
|
157
|
-
#
|
158
|
-
# @since v1.12.4
|
165
|
+
# Since v1.12.4
|
159
166
|
attr_accessor :namespace_inheritance
|
160
167
|
|
161
|
-
def initialize
|
168
|
+
def initialize(*args) # :nodoc:
|
162
169
|
@errors = []
|
163
170
|
@decorators = nil
|
164
171
|
@namespace_inheritance = false
|
165
172
|
end
|
166
173
|
|
167
|
-
|
168
|
-
#
|
169
|
-
#
|
174
|
+
# :call-seq:
|
175
|
+
# create_element(name, *contents_or_attrs, &block) → Nokogiri::XML::Element
|
176
|
+
#
|
177
|
+
# Create a new Element with `name` belonging to this document, optionally setting contents or
|
178
|
+
# attributes.
|
179
|
+
#
|
180
|
+
# This method is _not_ the most user-friendly option if your intention is to add a node to the
|
181
|
+
# document tree. Prefer one of the Nokogiri::XML::Node methods like Node#add_child,
|
182
|
+
# Node#add_next_sibling, Node#replace, etc. which will both create an element (or subtree) and
|
183
|
+
# place it in the document tree.
|
170
184
|
#
|
171
185
|
# Arguments may be passed to initialize the element:
|
172
|
-
#
|
173
|
-
# - a
|
186
|
+
#
|
187
|
+
# - a Hash argument will be used to set attributes
|
188
|
+
# - a non-Hash object that responds to \#to_s will be used to set the new node's contents
|
174
189
|
#
|
175
190
|
# A block may be passed to mutate the node.
|
176
191
|
#
|
177
|
-
#
|
178
|
-
#
|
179
|
-
#
|
180
|
-
#
|
192
|
+
# [Parameters]
|
193
|
+
# - `name` (String)
|
194
|
+
# - `contents_or_attrs` (\#to_s, Hash)
|
195
|
+
# [Yields] `node` (Nokogiri::XML::Element)
|
196
|
+
# [Returns] Nokogiri::XML::Element
|
197
|
+
#
|
198
|
+
# *Example:* An empty element without attributes
|
181
199
|
#
|
182
|
-
# @example An empty element without attributes
|
183
200
|
# doc.create_element("div")
|
184
201
|
# # => <div></div>
|
185
202
|
#
|
186
|
-
#
|
203
|
+
# *Example:* An element with contents
|
204
|
+
#
|
187
205
|
# doc.create_element("div", "contents")
|
188
206
|
# # => <div>contents</div>
|
189
207
|
#
|
190
|
-
#
|
208
|
+
# *Example:* An element with attributes
|
209
|
+
#
|
191
210
|
# doc.create_element("div", {"class" => "container"})
|
192
211
|
# # => <div class='container'></div>
|
193
212
|
#
|
194
|
-
#
|
213
|
+
# *Example:* An element with contents and attributes
|
214
|
+
#
|
195
215
|
# doc.create_element("div", "contents", {"class" => "container"})
|
196
216
|
# # => <div class='container'>contents</div>
|
197
217
|
#
|
198
|
-
#
|
218
|
+
# *Example:* Passing a block to mutate the element
|
219
|
+
#
|
199
220
|
# doc.create_element("div") { |node| node["class"] = "blue" if before_noon? }
|
200
221
|
#
|
201
222
|
def create_element(name, *contents_or_attrs, &block)
|
@@ -216,30 +237,30 @@ module Nokogiri
|
|
216
237
|
elm.content = arg
|
217
238
|
end
|
218
239
|
end
|
219
|
-
if ns = elm.namespace_definitions.find { |n| n.prefix.nil? || (n.prefix ==
|
240
|
+
if (ns = elm.namespace_definitions.find { |n| n.prefix.nil? || (n.prefix == "") })
|
220
241
|
elm.namespace = ns
|
221
242
|
end
|
222
243
|
elm
|
223
244
|
end
|
224
245
|
|
225
246
|
# Create a Text Node with +string+
|
226
|
-
def create_text_node
|
227
|
-
Nokogiri::XML::Text.new
|
247
|
+
def create_text_node(string, &block)
|
248
|
+
Nokogiri::XML::Text.new(string.to_s, self, &block)
|
228
249
|
end
|
229
250
|
|
230
251
|
# Create a CDATA Node containing +string+
|
231
|
-
def create_cdata
|
232
|
-
Nokogiri::XML::CDATA.new
|
252
|
+
def create_cdata(string, &block)
|
253
|
+
Nokogiri::XML::CDATA.new(self, string.to_s, &block)
|
233
254
|
end
|
234
255
|
|
235
256
|
# Create a Comment Node containing +string+
|
236
|
-
def create_comment
|
237
|
-
Nokogiri::XML::Comment.new
|
257
|
+
def create_comment(string, &block)
|
258
|
+
Nokogiri::XML::Comment.new(self, string.to_s, &block)
|
238
259
|
end
|
239
260
|
|
240
261
|
# The name of this document. Always returns "document"
|
241
262
|
def name
|
242
|
-
|
263
|
+
"document"
|
243
264
|
end
|
244
265
|
|
245
266
|
# A reference to +self+
|
@@ -247,46 +268,51 @@ module Nokogiri
|
|
247
268
|
self
|
248
269
|
end
|
249
270
|
|
250
|
-
|
251
|
-
#
|
252
|
-
# return them as a hash.
|
271
|
+
# :call-seq:
|
272
|
+
# collect_namespaces() → Hash<String(Namespace#prefix) ⇒ String(Namespace#href)>
|
253
273
|
#
|
254
|
-
#
|
274
|
+
# Recursively get all namespaces from this node and its subtree and return them as a
|
275
|
+
# hash.
|
255
276
|
#
|
256
|
-
#
|
277
|
+
# ⚠ This method will not handle duplicate namespace prefixes, since the return value is a hash.
|
278
|
+
#
|
279
|
+
# Note that this method does an xpath lookup for nodes with namespaces, and as a result the
|
280
|
+
# order (and which duplicate prefix "wins") may be dependent on the implementation of the
|
281
|
+
# underlying XML library.
|
282
|
+
#
|
283
|
+
# *Example:* Basic usage
|
284
|
+
#
|
285
|
+
# Given this document:
|
286
|
+
#
|
287
|
+
# <root xmlns="default" xmlns:foo="bar">
|
257
288
|
# <bar xmlns:hello="world" />
|
258
289
|
# </root>
|
259
290
|
#
|
260
291
|
# This method will return:
|
261
292
|
#
|
262
|
-
# {
|
293
|
+
# {"xmlns:foo"=>"bar", "xmlns"=>"default", "xmlns:hello"=>"world"}
|
263
294
|
#
|
264
|
-
#
|
265
|
-
#
|
295
|
+
# *Example:* Duplicate prefixes
|
296
|
+
#
|
297
|
+
# Given this document:
|
266
298
|
#
|
267
299
|
# <root xmlns:foo="bar">
|
268
300
|
# <bar xmlns:foo="baz" />
|
269
301
|
# </root>
|
270
302
|
#
|
271
|
-
# The hash returned will
|
272
|
-
#
|
273
|
-
# Non-prefixed default namespaces (as in "xmlns=") are not included
|
274
|
-
# in the hash.
|
303
|
+
# The hash returned will be something like:
|
275
304
|
#
|
276
|
-
#
|
277
|
-
# namespaces, and as a result the order may be dependent on the
|
278
|
-
# implementation of the underlying XML library.
|
305
|
+
# {"xmlns:foo" => "baz"}
|
279
306
|
#
|
280
307
|
def collect_namespaces
|
281
|
-
xpath("//namespace::*").
|
282
|
-
hash[["xmlns",ns.prefix].compact.join(":")] = ns.href if ns.prefix != "xml"
|
283
|
-
hash
|
308
|
+
xpath("//namespace::*").each_with_object({}) do |ns, hash|
|
309
|
+
hash[["xmlns", ns.prefix].compact.join(":")] = ns.href if ns.prefix != "xml"
|
284
310
|
end
|
285
311
|
end
|
286
312
|
|
287
313
|
# Get the list of decorators given +key+
|
288
|
-
def decorators
|
289
|
-
@decorators ||=
|
314
|
+
def decorators(key)
|
315
|
+
@decorators ||= {}
|
290
316
|
@decorators[key] ||= []
|
291
317
|
end
|
292
318
|
|
@@ -295,7 +321,7 @@ module Nokogiri
|
|
295
321
|
# the document or +nil+ when there is no DTD.
|
296
322
|
def validate
|
297
323
|
return nil unless internal_subset
|
298
|
-
internal_subset.validate
|
324
|
+
internal_subset.validate(self)
|
299
325
|
end
|
300
326
|
|
301
327
|
##
|
@@ -315,7 +341,7 @@ module Nokogiri
|
|
315
341
|
# ... which does absolutely nothing.
|
316
342
|
#
|
317
343
|
def slop!
|
318
|
-
unless decorators(XML::Node).include?
|
344
|
+
unless decorators(XML::Node).include?(Nokogiri::Decorators::Slop)
|
319
345
|
decorators(XML::Node) << Nokogiri::Decorators::Slop
|
320
346
|
decorate!
|
321
347
|
end
|
@@ -325,16 +351,16 @@ module Nokogiri
|
|
325
351
|
|
326
352
|
##
|
327
353
|
# Apply any decorators to +node+
|
328
|
-
def decorate
|
354
|
+
def decorate(node)
|
329
355
|
return unless @decorators
|
330
|
-
@decorators.each
|
356
|
+
@decorators.each do |klass, list|
|
331
357
|
next unless node.is_a?(klass)
|
332
358
|
list.each { |moodule| node.extend(moodule) }
|
333
|
-
|
359
|
+
end
|
334
360
|
end
|
335
361
|
|
336
|
-
|
337
|
-
|
362
|
+
alias_method :to_xml, :serialize
|
363
|
+
alias_method :clone, :dup
|
338
364
|
|
339
365
|
# Get the hash of namespaces on the root Nokogiri::XML::Node
|
340
366
|
def namespaces
|
@@ -344,16 +370,16 @@ module Nokogiri
|
|
344
370
|
##
|
345
371
|
# Create a Nokogiri::XML::DocumentFragment from +tags+
|
346
372
|
# Returns an empty fragment if +tags+ is nil.
|
347
|
-
def fragment
|
348
|
-
DocumentFragment.new(self, tags,
|
373
|
+
def fragment(tags = nil)
|
374
|
+
DocumentFragment.new(self, tags, root)
|
349
375
|
end
|
350
376
|
|
351
377
|
undef_method :swap, :parent, :namespace, :default_namespace=
|
352
378
|
undef_method :add_namespace_definition, :attributes
|
353
379
|
undef_method :namespace_definitions, :line, :add_namespace
|
354
380
|
|
355
|
-
def add_child
|
356
|
-
raise "A document may not have multiple root nodes." if (root && root.name !=
|
381
|
+
def add_child(node_or_tags)
|
382
|
+
raise "A document may not have multiple root nodes." if (root && root.name != "nokogiri_text_wrapper") && !(node_or_tags.comment? || node_or_tags.processing_instruction?)
|
357
383
|
node_or_tags = coerce(node_or_tags)
|
358
384
|
if node_or_tags.is_a?(XML::NodeSet)
|
359
385
|
raise "A document may not have multiple root nodes." if node_or_tags.size > 1
|
@@ -362,17 +388,27 @@ module Nokogiri
|
|
362
388
|
super
|
363
389
|
end
|
364
390
|
end
|
365
|
-
|
391
|
+
alias_method :<<, :add_child
|
392
|
+
|
393
|
+
# :call-seq:
|
394
|
+
# xpath_doctype() → Nokogiri::CSS::XPathVisitor::DoctypeConfig
|
395
|
+
#
|
396
|
+
# [Returns] The document type which determines CSS-to-XPath translation.
|
397
|
+
#
|
398
|
+
# See XPathVisitor for more information.
|
399
|
+
def xpath_doctype
|
400
|
+
Nokogiri::CSS::XPathVisitor::DoctypeConfig::XML
|
401
|
+
end
|
366
402
|
|
367
403
|
private
|
368
404
|
|
369
|
-
def self.empty_doc?
|
405
|
+
def self.empty_doc?(string_or_io)
|
370
406
|
string_or_io.nil? ||
|
371
407
|
(string_or_io.respond_to?(:empty?) && string_or_io.empty?) ||
|
372
408
|
(string_or_io.respond_to?(:eof?) && string_or_io.eof?)
|
373
409
|
end
|
374
410
|
|
375
|
-
IMPLIED_XPATH_CONTEXTS = [
|
411
|
+
IMPLIED_XPATH_CONTEXTS = ["//"].freeze # :nodoc:
|
376
412
|
|
377
413
|
def inspect_attributes
|
378
414
|
[:name, :children]
|