nokogiri 1.11.3 → 1.13.8
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/LICENSE-DEPENDENCIES.md +243 -22
- data/LICENSE.md +1 -1
- data/README.md +14 -11
- data/bin/nokogiri +63 -50
- data/dependencies.yml +13 -64
- data/ext/nokogiri/depend +35 -34
- data/ext/nokogiri/extconf.rb +237 -133
- data/ext/nokogiri/gumbo.c +584 -0
- data/ext/nokogiri/{html_document.c → html4_document.c} +8 -8
- data/ext/nokogiri/{html_element_description.c → html4_element_description.c} +21 -19
- data/ext/nokogiri/{html_entity_lookup.c → html4_entity_lookup.c} +7 -7
- data/ext/nokogiri/{html_sax_parser_context.c → html4_sax_parser_context.c} +8 -8
- data/ext/nokogiri/{html_sax_push_parser.c → html4_sax_push_parser.c} +4 -4
- data/ext/nokogiri/libxml2_backwards_compat.c +30 -30
- data/ext/nokogiri/nokogiri.c +70 -38
- data/ext/nokogiri/nokogiri.h +27 -9
- data/ext/nokogiri/xml_attr.c +2 -2
- data/ext/nokogiri/xml_attribute_decl.c +3 -3
- data/ext/nokogiri/xml_cdata.c +1 -1
- data/ext/nokogiri/xml_document.c +50 -50
- data/ext/nokogiri/xml_document_fragment.c +0 -2
- data/ext/nokogiri/xml_dtd.c +10 -10
- data/ext/nokogiri/xml_element_content.c +2 -0
- data/ext/nokogiri/xml_element_decl.c +3 -3
- data/ext/nokogiri/xml_encoding_handler.c +31 -12
- data/ext/nokogiri/xml_entity_decl.c +5 -5
- data/ext/nokogiri/xml_namespace.c +4 -2
- data/ext/nokogiri/xml_node.c +833 -492
- data/ext/nokogiri/xml_node_set.c +24 -24
- data/ext/nokogiri/xml_reader.c +90 -11
- data/ext/nokogiri/xml_sax_parser.c +6 -6
- data/ext/nokogiri/xml_sax_parser_context.c +12 -3
- data/ext/nokogiri/xml_schema.c +5 -3
- data/ext/nokogiri/xml_text.c +1 -1
- data/ext/nokogiri/xml_xpath_context.c +110 -85
- data/ext/nokogiri/xslt_stylesheet.c +109 -10
- data/gumbo-parser/CHANGES.md +63 -0
- data/gumbo-parser/Makefile +101 -0
- data/gumbo-parser/THANKS +27 -0
- data/gumbo-parser/src/Makefile +34 -0
- data/gumbo-parser/src/README.md +41 -0
- data/gumbo-parser/src/ascii.c +75 -0
- data/gumbo-parser/src/ascii.h +115 -0
- data/gumbo-parser/src/attribute.c +42 -0
- data/gumbo-parser/src/attribute.h +17 -0
- data/gumbo-parser/src/char_ref.c +22225 -0
- data/gumbo-parser/src/char_ref.h +29 -0
- data/gumbo-parser/src/char_ref.rl +2154 -0
- data/gumbo-parser/src/error.c +626 -0
- data/gumbo-parser/src/error.h +148 -0
- data/gumbo-parser/src/foreign_attrs.c +104 -0
- data/gumbo-parser/src/foreign_attrs.gperf +27 -0
- data/gumbo-parser/src/gumbo.h +943 -0
- data/gumbo-parser/src/insertion_mode.h +33 -0
- data/gumbo-parser/src/macros.h +91 -0
- data/gumbo-parser/src/parser.c +4875 -0
- data/gumbo-parser/src/parser.h +41 -0
- data/gumbo-parser/src/replacement.h +33 -0
- data/gumbo-parser/src/string_buffer.c +103 -0
- data/gumbo-parser/src/string_buffer.h +68 -0
- data/gumbo-parser/src/string_piece.c +48 -0
- data/gumbo-parser/src/svg_attrs.c +174 -0
- data/gumbo-parser/src/svg_attrs.gperf +77 -0
- data/gumbo-parser/src/svg_tags.c +137 -0
- data/gumbo-parser/src/svg_tags.gperf +55 -0
- data/gumbo-parser/src/tag.c +222 -0
- data/gumbo-parser/src/tag_lookup.c +382 -0
- data/gumbo-parser/src/tag_lookup.gperf +169 -0
- data/gumbo-parser/src/tag_lookup.h +13 -0
- data/gumbo-parser/src/token_buffer.c +79 -0
- data/gumbo-parser/src/token_buffer.h +71 -0
- data/gumbo-parser/src/token_type.h +17 -0
- data/gumbo-parser/src/tokenizer.c +3463 -0
- data/gumbo-parser/src/tokenizer.h +112 -0
- data/gumbo-parser/src/tokenizer_states.h +339 -0
- data/gumbo-parser/src/utf8.c +245 -0
- data/gumbo-parser/src/utf8.h +164 -0
- data/gumbo-parser/src/util.c +68 -0
- data/gumbo-parser/src/util.h +30 -0
- data/gumbo-parser/src/vector.c +111 -0
- data/gumbo-parser/src/vector.h +45 -0
- data/lib/nokogiri/class_resolver.rb +67 -0
- data/lib/nokogiri/css/node.rb +9 -8
- data/lib/nokogiri/css/parser.rb +361 -342
- data/lib/nokogiri/css/parser.y +250 -245
- data/lib/nokogiri/css/parser_extras.rb +22 -20
- data/lib/nokogiri/css/syntax_error.rb +2 -1
- data/lib/nokogiri/css/tokenizer.rb +4 -3
- data/lib/nokogiri/css/tokenizer.rex +3 -2
- data/lib/nokogiri/css/xpath_visitor.rb +179 -82
- data/lib/nokogiri/css.rb +49 -17
- data/lib/nokogiri/decorators/slop.rb +8 -7
- data/lib/nokogiri/extension.rb +8 -3
- data/lib/nokogiri/gumbo.rb +15 -0
- data/lib/nokogiri/html.rb +37 -27
- data/lib/nokogiri/{html → html4}/builder.rb +3 -2
- data/lib/nokogiri/{html → html4}/document.rb +92 -81
- data/lib/nokogiri/{html → html4}/document_fragment.rb +13 -9
- data/lib/nokogiri/{html → html4}/element_description.rb +2 -1
- data/lib/nokogiri/html4/element_description_defaults.rb +578 -0
- data/lib/nokogiri/{html → html4}/entity_lookup.rb +3 -2
- data/lib/nokogiri/{html → html4}/sax/parser.rb +16 -16
- data/lib/nokogiri/html4/sax/parser_context.rb +20 -0
- data/lib/nokogiri/{html → html4}/sax/push_parser.rb +11 -11
- data/lib/nokogiri/html4.rb +46 -0
- data/lib/nokogiri/html5/document.rb +91 -0
- data/lib/nokogiri/html5/document_fragment.rb +83 -0
- data/lib/nokogiri/html5/node.rb +100 -0
- data/lib/nokogiri/html5.rb +478 -0
- 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 +31 -14
- 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 +71 -31
- data/lib/nokogiri/xml/cdata.rb +2 -1
- data/lib/nokogiri/xml/character_data.rb +1 -0
- data/lib/nokogiri/xml/document.rb +183 -96
- 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 +9 -5
- data/lib/nokogiri/xml/node.rb +525 -354
- data/lib/nokogiri/xml/node_set.rb +50 -54
- data/lib/nokogiri/xml/notation.rb +12 -0
- data/lib/nokogiri/xml/parse_options.rb +13 -6
- 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 +3 -2
- data/lib/nokogiri/xml/processing_instruction.rb +2 -1
- data/lib/nokogiri/xml/reader.rb +20 -24
- data/lib/nokogiri/xml/relax_ng.rb +1 -0
- data/lib/nokogiri/xml/sax/document.rb +44 -49
- data/lib/nokogiri/xml/sax/parser.rb +37 -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 +5 -4
- data/lib/nokogiri/xml/schema.rb +7 -6
- data/lib/nokogiri/xml/searchable.rb +93 -62
- data/lib/nokogiri/xml/syntax_error.rb +5 -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 +13 -1
- data/lib/nokogiri/xml/xpath_context.rb +2 -3
- data/lib/nokogiri/xml.rb +37 -37
- data/lib/nokogiri/xslt/stylesheet.rb +2 -1
- data/lib/nokogiri/xslt.rb +28 -20
- data/lib/nokogiri.rb +48 -43
- data/lib/xsd/xmlparser/nokogiri.rb +25 -24
- data/patches/libxml2/{0002-Remove-script-macro-support.patch → 0001-Remove-script-macro-support.patch} +0 -0
- data/patches/libxml2/{0003-Update-entities-to-remove-handling-of-ssi.patch → 0002-Update-entities-to-remove-handling-of-ssi.patch} +0 -0
- data/patches/libxml2/{0004-libxml2.la-is-in-top_builddir.patch → 0003-libxml2.la-is-in-top_builddir.patch} +1 -1
- data/patches/libxml2/{0008-use-glibc-strlen.patch → 0004-use-glibc-strlen.patch} +3 -3
- data/patches/libxml2/{0009-avoid-isnan-isinf.patch → 0005-avoid-isnan-isinf.patch} +4 -4
- data/patches/libxml2/0006-update-automake-files-for-arm64.patch +3040 -0
- data/patches/libxml2/0008-htmlParseComment-handle-abruptly-closed-comments.patch +61 -0
- data/patches/libxml2/0009-allow-wildcard-namespaces.patch +77 -0
- data/patches/libxslt/0001-update-automake-files-for-arm64.patch +2445 -1919
- data/ports/archives/libxml2-2.9.14.tar.xz +0 -0
- data/ports/archives/libxslt-1.1.35.tar.xz +0 -0
- metadata +204 -93
- data/lib/nokogiri/html/element_description_defaults.rb +0 -672
- data/lib/nokogiri/html/sax/parser_context.rb +0 -17
- data/patches/libxml2/0001-Revert-Do-not-URI-escape-in-server-side-includes.patch +0 -78
- data/patches/libxml2/0005-Fix-infinite-loop-in-xmlStringLenDecodeEntities.patch +0 -32
- data/patches/libxml2/0006-htmlParseComment-treat-as-if-it-closed-the-comment.patch +0 -73
- data/patches/libxml2/0007-use-new-htmlParseLookupCommentEnd-to-find-comment-en.patch +0 -103
- data/patches/libxml2/0010-parser.c-shrink-the-input-buffer-when-appropriate.patch +0 -70
- data/patches/libxml2/0011-update-automake-files-for-arm64.patch +0 -2511
- data/ports/archives/libxml2-2.9.10.tar.gz +0 -0
- data/ports/archives/libxslt-1.1.34.tar.gz +0 -0
@@ -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,109 +45,178 @@ 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
|
-
|
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
|
127
|
+
#
|
128
|
+
# xml = <<~EOF
|
129
|
+
# <root xmlns:foo="http://nokogiri.org/default_ns/test/foo">
|
130
|
+
# <foo:parent>
|
131
|
+
# </foo:parent>
|
132
|
+
# </root>
|
133
|
+
# EOF
|
134
|
+
# doc = Nokogiri::XML(xml)
|
135
|
+
# parent = doc.at_xpath("//foo:parent", "foo" => "http://nokogiri.org/default_ns/test/foo")
|
136
|
+
# parent.add_child("<child></child>")
|
137
|
+
# doc.to_xml
|
138
|
+
# # => <?xml version="1.0"?>
|
139
|
+
# # <root xmlns:foo="http://nokogiri.org/default_ns/test/foo">
|
140
|
+
# # <foo:parent>
|
141
|
+
# # <child/>
|
142
|
+
# # </foo:parent>
|
143
|
+
# # </root>
|
144
|
+
#
|
145
|
+
# *Example:* Setting namespace inheritance to `true`
|
146
|
+
#
|
147
|
+
# xml = <<~EOF
|
148
|
+
# <root xmlns:foo="http://nokogiri.org/default_ns/test/foo">
|
149
|
+
# <foo:parent>
|
150
|
+
# </foo:parent>
|
151
|
+
# </root>
|
152
|
+
# EOF
|
153
|
+
# doc = Nokogiri::XML(xml)
|
154
|
+
# doc.namespace_inheritance = true
|
155
|
+
# parent = doc.at_xpath("//foo:parent", "foo" => "http://nokogiri.org/default_ns/test/foo")
|
156
|
+
# parent.add_child("<child></child>")
|
157
|
+
# doc.to_xml
|
158
|
+
# # => <?xml version="1.0"?>
|
159
|
+
# # <root xmlns:foo="http://nokogiri.org/default_ns/test/foo">
|
160
|
+
# # <foo:parent>
|
161
|
+
# # <foo:child/>
|
162
|
+
# # </foo:parent>
|
163
|
+
# # </root>
|
164
|
+
#
|
165
|
+
# Since v1.12.4
|
166
|
+
attr_accessor :namespace_inheritance
|
167
|
+
|
168
|
+
def initialize(*args) # :nodoc:
|
117
169
|
@errors = []
|
118
170
|
@decorators = nil
|
171
|
+
@namespace_inheritance = false
|
119
172
|
end
|
120
173
|
|
121
|
-
|
122
|
-
#
|
123
|
-
#
|
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.
|
124
184
|
#
|
125
185
|
# Arguments may be passed to initialize the element:
|
126
|
-
#
|
127
|
-
# - 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
|
128
189
|
#
|
129
190
|
# A block may be passed to mutate the node.
|
130
191
|
#
|
131
|
-
#
|
132
|
-
#
|
133
|
-
#
|
134
|
-
#
|
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
|
135
199
|
#
|
136
|
-
# @example An empty element without attributes
|
137
200
|
# doc.create_element("div")
|
138
201
|
# # => <div></div>
|
139
202
|
#
|
140
|
-
#
|
203
|
+
# *Example:* An element with contents
|
204
|
+
#
|
141
205
|
# doc.create_element("div", "contents")
|
142
206
|
# # => <div>contents</div>
|
143
207
|
#
|
144
|
-
#
|
208
|
+
# *Example:* An element with attributes
|
209
|
+
#
|
145
210
|
# doc.create_element("div", {"class" => "container"})
|
146
211
|
# # => <div class='container'></div>
|
147
212
|
#
|
148
|
-
#
|
213
|
+
# *Example:* An element with contents and attributes
|
214
|
+
#
|
149
215
|
# doc.create_element("div", "contents", {"class" => "container"})
|
150
216
|
# # => <div class='container'>contents</div>
|
151
217
|
#
|
152
|
-
#
|
218
|
+
# *Example:* Passing a block to mutate the element
|
219
|
+
#
|
153
220
|
# doc.create_element("div") { |node| node["class"] = "blue" if before_noon? }
|
154
221
|
#
|
155
222
|
def create_element(name, *contents_or_attrs, &block)
|
@@ -170,30 +237,30 @@ module Nokogiri
|
|
170
237
|
elm.content = arg
|
171
238
|
end
|
172
239
|
end
|
173
|
-
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 == "") })
|
174
241
|
elm.namespace = ns
|
175
242
|
end
|
176
243
|
elm
|
177
244
|
end
|
178
245
|
|
179
246
|
# Create a Text Node with +string+
|
180
|
-
def create_text_node
|
181
|
-
Nokogiri::XML::Text.new
|
247
|
+
def create_text_node(string, &block)
|
248
|
+
Nokogiri::XML::Text.new(string.to_s, self, &block)
|
182
249
|
end
|
183
250
|
|
184
251
|
# Create a CDATA Node containing +string+
|
185
|
-
def create_cdata
|
186
|
-
Nokogiri::XML::CDATA.new
|
252
|
+
def create_cdata(string, &block)
|
253
|
+
Nokogiri::XML::CDATA.new(self, string.to_s, &block)
|
187
254
|
end
|
188
255
|
|
189
256
|
# Create a Comment Node containing +string+
|
190
|
-
def create_comment
|
191
|
-
Nokogiri::XML::Comment.new
|
257
|
+
def create_comment(string, &block)
|
258
|
+
Nokogiri::XML::Comment.new(self, string.to_s, &block)
|
192
259
|
end
|
193
260
|
|
194
261
|
# The name of this document. Always returns "document"
|
195
262
|
def name
|
196
|
-
|
263
|
+
"document"
|
197
264
|
end
|
198
265
|
|
199
266
|
# A reference to +self+
|
@@ -201,46 +268,51 @@ module Nokogiri
|
|
201
268
|
self
|
202
269
|
end
|
203
270
|
|
204
|
-
|
205
|
-
#
|
206
|
-
# return them as a hash.
|
271
|
+
# :call-seq:
|
272
|
+
# collect_namespaces() → Hash<String(Namespace#prefix) ⇒ String(Namespace#href)>
|
207
273
|
#
|
208
|
-
#
|
274
|
+
# Recursively get all namespaces from this node and its subtree and return them as a
|
275
|
+
# hash.
|
209
276
|
#
|
210
|
-
#
|
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">
|
211
288
|
# <bar xmlns:hello="world" />
|
212
289
|
# </root>
|
213
290
|
#
|
214
291
|
# This method will return:
|
215
292
|
#
|
216
|
-
# {
|
293
|
+
# {"xmlns:foo"=>"bar", "xmlns"=>"default", "xmlns:hello"=>"world"}
|
217
294
|
#
|
218
|
-
#
|
219
|
-
#
|
295
|
+
# *Example:* Duplicate prefixes
|
296
|
+
#
|
297
|
+
# Given this document:
|
220
298
|
#
|
221
299
|
# <root xmlns:foo="bar">
|
222
300
|
# <bar xmlns:foo="baz" />
|
223
301
|
# </root>
|
224
302
|
#
|
225
|
-
# The hash returned will
|
226
|
-
#
|
227
|
-
# Non-prefixed default namespaces (as in "xmlns=") are not included
|
228
|
-
# in the hash.
|
303
|
+
# The hash returned will be something like:
|
229
304
|
#
|
230
|
-
#
|
231
|
-
# namespaces, and as a result the order may be dependent on the
|
232
|
-
# implementation of the underlying XML library.
|
305
|
+
# {"xmlns:foo" => "baz"}
|
233
306
|
#
|
234
307
|
def collect_namespaces
|
235
|
-
xpath("//namespace::*").
|
236
|
-
hash[["xmlns",ns.prefix].compact.join(":")] = ns.href if ns.prefix != "xml"
|
237
|
-
hash
|
308
|
+
xpath("//namespace::*").each_with_object({}) do |ns, hash|
|
309
|
+
hash[["xmlns", ns.prefix].compact.join(":")] = ns.href if ns.prefix != "xml"
|
238
310
|
end
|
239
311
|
end
|
240
312
|
|
241
313
|
# Get the list of decorators given +key+
|
242
|
-
def decorators
|
243
|
-
@decorators ||=
|
314
|
+
def decorators(key)
|
315
|
+
@decorators ||= {}
|
244
316
|
@decorators[key] ||= []
|
245
317
|
end
|
246
318
|
|
@@ -249,7 +321,8 @@ module Nokogiri
|
|
249
321
|
# the document or +nil+ when there is no DTD.
|
250
322
|
def validate
|
251
323
|
return nil unless internal_subset
|
252
|
-
|
324
|
+
|
325
|
+
internal_subset.validate(self)
|
253
326
|
end
|
254
327
|
|
255
328
|
##
|
@@ -269,7 +342,7 @@ module Nokogiri
|
|
269
342
|
# ... which does absolutely nothing.
|
270
343
|
#
|
271
344
|
def slop!
|
272
|
-
unless decorators(XML::Node).include?
|
345
|
+
unless decorators(XML::Node).include?(Nokogiri::Decorators::Slop)
|
273
346
|
decorators(XML::Node) << Nokogiri::Decorators::Slop
|
274
347
|
decorate!
|
275
348
|
end
|
@@ -279,16 +352,18 @@ module Nokogiri
|
|
279
352
|
|
280
353
|
##
|
281
354
|
# Apply any decorators to +node+
|
282
|
-
def decorate
|
355
|
+
def decorate(node)
|
283
356
|
return unless @decorators
|
284
|
-
|
357
|
+
|
358
|
+
@decorators.each do |klass, list|
|
285
359
|
next unless node.is_a?(klass)
|
360
|
+
|
286
361
|
list.each { |moodule| node.extend(moodule) }
|
287
|
-
|
362
|
+
end
|
288
363
|
end
|
289
364
|
|
290
|
-
|
291
|
-
|
365
|
+
alias_method :to_xml, :serialize
|
366
|
+
alias_method :clone, :dup
|
292
367
|
|
293
368
|
# Get the hash of namespaces on the root Nokogiri::XML::Node
|
294
369
|
def namespaces
|
@@ -298,35 +373,47 @@ module Nokogiri
|
|
298
373
|
##
|
299
374
|
# Create a Nokogiri::XML::DocumentFragment from +tags+
|
300
375
|
# Returns an empty fragment if +tags+ is nil.
|
301
|
-
def fragment
|
302
|
-
DocumentFragment.new(self, tags,
|
376
|
+
def fragment(tags = nil)
|
377
|
+
DocumentFragment.new(self, tags, root)
|
303
378
|
end
|
304
379
|
|
305
380
|
undef_method :swap, :parent, :namespace, :default_namespace=
|
306
381
|
undef_method :add_namespace_definition, :attributes
|
307
382
|
undef_method :namespace_definitions, :line, :add_namespace
|
308
383
|
|
309
|
-
def add_child
|
310
|
-
raise "A document may not have multiple root nodes." if (root && root.name !=
|
384
|
+
def add_child(node_or_tags)
|
385
|
+
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?)
|
386
|
+
|
311
387
|
node_or_tags = coerce(node_or_tags)
|
312
388
|
if node_or_tags.is_a?(XML::NodeSet)
|
313
389
|
raise "A document may not have multiple root nodes." if node_or_tags.size > 1
|
390
|
+
|
314
391
|
super(node_or_tags.first)
|
315
392
|
else
|
316
393
|
super
|
317
394
|
end
|
318
395
|
end
|
319
|
-
|
396
|
+
alias_method :<<, :add_child
|
397
|
+
|
398
|
+
# :call-seq:
|
399
|
+
# xpath_doctype() → Nokogiri::CSS::XPathVisitor::DoctypeConfig
|
400
|
+
#
|
401
|
+
# [Returns] The document type which determines CSS-to-XPath translation.
|
402
|
+
#
|
403
|
+
# See XPathVisitor for more information.
|
404
|
+
def xpath_doctype
|
405
|
+
Nokogiri::CSS::XPathVisitor::DoctypeConfig::XML
|
406
|
+
end
|
320
407
|
|
321
408
|
private
|
322
409
|
|
323
|
-
def self.empty_doc?
|
410
|
+
def self.empty_doc?(string_or_io)
|
324
411
|
string_or_io.nil? ||
|
325
412
|
(string_or_io.respond_to?(:empty?) && string_or_io.empty?) ||
|
326
413
|
(string_or_io.respond_to?(:eof?) && string_or_io.eof?)
|
327
414
|
end
|
328
415
|
|
329
|
-
IMPLIED_XPATH_CONTEXTS = [
|
416
|
+
IMPLIED_XPATH_CONTEXTS = ["//"].freeze # :nodoc:
|
330
417
|
|
331
418
|
def inspect_attributes
|
332
419
|
[:name, :children]
|
@@ -1,28 +1,39 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Nokogiri
|
3
4
|
module XML
|
4
5
|
class DocumentFragment < Nokogiri::XML::Node
|
6
|
+
####
|
7
|
+
# Create a Nokogiri::XML::DocumentFragment from +tags+
|
8
|
+
def self.parse(tags, options = ParseOptions::DEFAULT_XML, &block)
|
9
|
+
new(XML::Document.new, tags, nil, options, &block)
|
10
|
+
end
|
11
|
+
|
5
12
|
##
|
6
13
|
# Create a new DocumentFragment from +tags+.
|
7
14
|
#
|
8
15
|
# If +ctx+ is present, it is used as a context node for the
|
9
16
|
# subtree created, e.g., namespaces will be resolved relative
|
10
17
|
# to +ctx+.
|
11
|
-
def initialize
|
18
|
+
def initialize(document, tags = nil, ctx = nil, options = ParseOptions::DEFAULT_XML)
|
12
19
|
return self unless tags
|
13
20
|
|
21
|
+
options = Nokogiri::XML::ParseOptions.new(options) if Integer === options
|
22
|
+
yield options if block_given?
|
23
|
+
|
14
24
|
children = if ctx
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
25
|
+
# Fix for issue#490
|
26
|
+
if Nokogiri.jruby?
|
27
|
+
# fix for issue #770
|
28
|
+
ctx.parse("<root #{namespace_declarations(ctx)}>#{tags}</root>", options).children
|
29
|
+
else
|
30
|
+
ctx.parse(tags, options)
|
31
|
+
end
|
32
|
+
else
|
33
|
+
wrapper_doc = XML::Document.parse("<root>#{tags}</root>", nil, nil, options)
|
34
|
+
self.errors = wrapper_doc.errors
|
35
|
+
wrapper_doc.xpath("/root/node()")
|
36
|
+
end
|
26
37
|
children.each { |child| child.parent = self }
|
27
38
|
end
|
28
39
|
|
@@ -40,7 +51,7 @@ module Nokogiri
|
|
40
51
|
###
|
41
52
|
# return the name for DocumentFragment
|
42
53
|
def name
|
43
|
-
|
54
|
+
"#document-fragment"
|
44
55
|
end
|
45
56
|
|
46
57
|
###
|
@@ -52,10 +63,10 @@ module Nokogiri
|
|
52
63
|
###
|
53
64
|
# Convert this DocumentFragment to html
|
54
65
|
# See Nokogiri::XML::NodeSet#to_html
|
55
|
-
def to_html
|
66
|
+
def to_html(*args)
|
56
67
|
if Nokogiri.jruby?
|
57
68
|
options = args.first.is_a?(Hash) ? args.shift : {}
|
58
|
-
|
69
|
+
unless options[:save_with]
|
59
70
|
options[:save_with] = Node::SaveOptions::NO_DECLARATION | Node::SaveOptions::NO_EMPTY_TAGS | Node::SaveOptions::AS_HTML
|
60
71
|
end
|
61
72
|
args.insert(0, options)
|
@@ -66,10 +77,10 @@ module Nokogiri
|
|
66
77
|
###
|
67
78
|
# Convert this DocumentFragment to xhtml
|
68
79
|
# See Nokogiri::XML::NodeSet#to_xhtml
|
69
|
-
def to_xhtml
|
80
|
+
def to_xhtml(*args)
|
70
81
|
if Nokogiri.jruby?
|
71
82
|
options = args.first.is_a?(Hash) ? args.shift : {}
|
72
|
-
|
83
|
+
unless options[:save_with]
|
73
84
|
options[:save_with] = Node::SaveOptions::NO_DECLARATION | Node::SaveOptions::NO_EMPTY_TAGS | Node::SaveOptions::AS_XHTML
|
74
85
|
end
|
75
86
|
args.insert(0, options)
|
@@ -80,7 +91,7 @@ module Nokogiri
|
|
80
91
|
###
|
81
92
|
# Convert this DocumentFragment to xml
|
82
93
|
# See Nokogiri::XML::NodeSet#to_xml
|
83
|
-
def to_xml
|
94
|
+
def to_xml(*args)
|
84
95
|
children.to_xml(*args)
|
85
96
|
end
|
86
97
|
|
@@ -91,7 +102,7 @@ module Nokogiri
|
|
91
102
|
# selectors. For example:
|
92
103
|
#
|
93
104
|
# For more information see Nokogiri::XML::Searchable#css
|
94
|
-
def css
|
105
|
+
def css(*args)
|
95
106
|
if children.any?
|
96
107
|
children.css(*args) # 'children' is a smell here
|
97
108
|
else
|
@@ -110,34 +121,26 @@ module Nokogiri
|
|
110
121
|
# Search this fragment for +paths+. +paths+ must be one or more XPath or CSS queries.
|
111
122
|
#
|
112
123
|
# For more information see Nokogiri::XML::Searchable#search
|
113
|
-
def search
|
124
|
+
def search(*rules)
|
114
125
|
rules, handler, ns, binds = extract_params(rules)
|
115
126
|
|
116
127
|
rules.inject(NodeSet.new(document)) do |set, rule|
|
117
|
-
set
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
128
|
+
set + if Searchable::LOOKS_LIKE_XPATH.match?(rule)
|
129
|
+
xpath(*[rule, ns, handler, binds].compact)
|
130
|
+
else
|
131
|
+
children.css(*[rule, ns, handler].compact) # 'children' is a smell here
|
132
|
+
end
|
122
133
|
end
|
123
134
|
end
|
124
135
|
|
125
|
-
|
126
|
-
|
127
|
-
class << self
|
128
|
-
####
|
129
|
-
# Create a Nokogiri::XML::DocumentFragment from +tags+
|
130
|
-
def parse tags
|
131
|
-
self.new(XML::Document.new, tags)
|
132
|
-
end
|
133
|
-
end
|
136
|
+
alias_method :serialize, :to_s
|
134
137
|
|
135
138
|
# A list of Nokogiri::XML::SyntaxError found when parsing a document
|
136
139
|
def errors
|
137
140
|
document.errors
|
138
141
|
end
|
139
142
|
|
140
|
-
def errors=
|
143
|
+
def errors=(things) # :nodoc:
|
141
144
|
document.errors = things
|
142
145
|
end
|
143
146
|
|
@@ -148,11 +151,11 @@ module Nokogiri
|
|
148
151
|
private
|
149
152
|
|
150
153
|
# fix for issue 770
|
151
|
-
def namespace_declarations
|
154
|
+
def namespace_declarations(ctx)
|
152
155
|
ctx.namespace_scopes.map do |namespace|
|
153
156
|
prefix = namespace.prefix.nil? ? "" : ":#{namespace.prefix}"
|
154
|
-
%
|
155
|
-
end.join
|
157
|
+
%{xmlns#{prefix}="#{namespace.href}"}
|
158
|
+
end.join(" ")
|
156
159
|
end
|
157
160
|
end
|
158
161
|
end
|
data/lib/nokogiri/xml/dtd.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Nokogiri
|
3
4
|
module XML
|
4
5
|
class DTD < Nokogiri::XML::Node
|
@@ -20,13 +21,13 @@ module Nokogiri
|
|
20
21
|
end
|
21
22
|
|
22
23
|
def html_dtd?
|
23
|
-
name.casecmp(
|
24
|
+
name.casecmp("html").zero?
|
24
25
|
end
|
25
26
|
|
26
27
|
def html5_dtd?
|
27
28
|
html_dtd? &&
|
28
29
|
external_id.nil? &&
|
29
|
-
(system_id.nil? || system_id ==
|
30
|
+
(system_id.nil? || system_id == "about:legacy-compat")
|
30
31
|
end
|
31
32
|
end
|
32
33
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Nokogiri
|
3
4
|
module XML
|
4
5
|
class ElementDecl < Nokogiri::XML::Node
|
@@ -7,7 +8,7 @@ module Nokogiri
|
|
7
8
|
undef_method :line if method_defined?(:line)
|
8
9
|
|
9
10
|
def inspect
|
10
|
-
"#<#{self.class.name}:#{
|
11
|
+
"#<#{self.class.name}:#{format("0x%x", object_id)} #{to_s.inspect}>"
|
11
12
|
end
|
12
13
|
end
|
13
14
|
end
|