nokogiri-maglev- 1.5.0.1 → 1.5.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.ja.rdoc +56 -12
- data/CHANGELOG.rdoc +49 -0
- data/C_CODING_STYLE.rdoc +27 -0
- data/Manifest.txt +4 -0
- data/README.rdoc +11 -7
- data/Rakefile +42 -27
- data/bin/nokogiri +10 -2
- data/ext/nokogiri/extconf.rb +11 -3
- data/ext/nokogiri/html_document.c +16 -0
- data/ext/nokogiri/html_sax_parser_context.c +59 -37
- data/ext/nokogiri/html_sax_push_parser.c +87 -0
- data/ext/nokogiri/html_sax_push_parser.h +9 -0
- data/ext/nokogiri/nokogiri.c +7 -9
- data/ext/nokogiri/nokogiri.h +3 -0
- data/ext/nokogiri/xml_document.c +101 -3
- data/ext/nokogiri/xml_document.h +3 -3
- data/ext/nokogiri/xml_node.c +151 -58
- data/ext/nokogiri/xml_node_set.c +169 -120
- data/ext/nokogiri/xml_node_set.h +5 -0
- data/ext/nokogiri/xml_sax_parser_context.c +64 -41
- data/ext/nokogiri/xml_text.c +2 -0
- data/ext/nokogiri/xml_xpath_context.c +31 -25
- data/ext/nokogiri/xslt_stylesheet.c +62 -16
- data/ext/nokogiri/xslt_stylesheet.h +5 -0
- data/lib/nokogiri/css/parser.rb +165 -159
- data/lib/nokogiri/css/parser.y +6 -3
- data/lib/nokogiri/css/tokenizer.rb +1 -1
- data/lib/nokogiri/css/tokenizer.rex +1 -1
- data/lib/nokogiri/html.rb +1 -0
- data/lib/nokogiri/html/document.rb +82 -42
- data/lib/nokogiri/html/sax/push_parser.rb +16 -0
- data/lib/nokogiri/version.rb +1 -1
- data/lib/nokogiri/xml.rb +6 -0
- data/lib/nokogiri/xml/builder.rb +7 -1
- data/lib/nokogiri/xml/document.rb +32 -17
- data/lib/nokogiri/xml/document_fragment.rb +6 -1
- data/lib/nokogiri/xml/node.rb +40 -9
- data/lib/nokogiri/xslt.rb +5 -1
- data/tasks/cross_compile.rb +1 -0
- data/tasks/nokogiri.org.rb +6 -0
- data/tasks/test.rb +1 -0
- data/test/css/test_xpath_visitor.rb +6 -0
- data/test/helper.rb +1 -0
- data/test/html/test_document.rb +26 -0
- data/test/html/test_document_fragment.rb +1 -2
- data/test/test_memory_leak.rb +81 -1
- data/test/test_xslt_transforms.rb +152 -123
- data/test/xml/test_builder.rb +24 -2
- data/test/xml/test_c14n.rb +151 -0
- data/test/xml/test_document.rb +48 -0
- data/test/xml/test_namespace.rb +5 -0
- data/test/xml/test_node.rb +82 -1
- data/test/xml/test_node_attributes.rb +19 -0
- data/test/xml/test_node_inheritance.rb +32 -0
- data/test/xml/test_node_reparenting.rb +32 -0
- data/test/xml/test_node_set.rb +16 -8
- data/test/xml/test_reader_encoding.rb +16 -0
- data/test/xml/test_unparented_node.rb +32 -0
- data/test/xml/test_xinclude.rb +83 -0
- data/test/xml/test_xpath.rb +22 -0
- metadata +208 -241
data/lib/nokogiri/css/parser.y
CHANGED
@@ -69,6 +69,10 @@ rule
|
|
69
69
|
: '.' IDENT { result = Node.new(:CLASS_CONDITION, [val[1]]) }
|
70
70
|
;
|
71
71
|
element_name
|
72
|
+
: namespaced_ident
|
73
|
+
| '*' { result = Node.new(:ELEMENT_NAME, val) }
|
74
|
+
;
|
75
|
+
namespaced_ident
|
72
76
|
: namespace '|' IDENT {
|
73
77
|
result = Node.new(:ELEMENT_NAME,
|
74
78
|
[[val.first, val.last].compact.join(':')]
|
@@ -78,16 +82,15 @@ rule
|
|
78
82
|
name = @namespaces.key?('xmlns') ? "xmlns:#{val.first}" : val.first
|
79
83
|
result = Node.new(:ELEMENT_NAME, [name])
|
80
84
|
}
|
81
|
-
| '*' { result = Node.new(:ELEMENT_NAME, val) }
|
82
85
|
;
|
83
86
|
namespace
|
84
87
|
: IDENT { result = val[0] }
|
85
88
|
|
|
86
89
|
;
|
87
90
|
attrib
|
88
|
-
: LSQUARE
|
91
|
+
: LSQUARE namespaced_ident attrib_val_0or1 RSQUARE {
|
89
92
|
result = Node.new(:ATTRIBUTE_CONDITION,
|
90
|
-
[
|
93
|
+
[val[1]] + (val[2] || [])
|
91
94
|
)
|
92
95
|
}
|
93
96
|
| LSQUARE function attrib_val_0or1 RSQUARE {
|
data/lib/nokogiri/html.rb
CHANGED
@@ -3,6 +3,7 @@ require 'nokogiri/html/document'
|
|
3
3
|
require 'nokogiri/html/document_fragment'
|
4
4
|
require 'nokogiri/html/sax/parser_context'
|
5
5
|
require 'nokogiri/html/sax/parser'
|
6
|
+
require 'nokogiri/html/sax/push_parser'
|
6
7
|
require 'nokogiri/html/element_description'
|
7
8
|
require 'nokogiri/html/element_description_defaults'
|
8
9
|
|
@@ -19,7 +19,9 @@ module Nokogiri
|
|
19
19
|
|
20
20
|
def meta_content_type
|
21
21
|
css('meta[@http-equiv]').find { |node|
|
22
|
-
node['http-equiv'] =~ /\AContent-Type\z/i
|
22
|
+
node['http-equiv'] =~ /\AContent-Type\z/i and
|
23
|
+
!node['content'].nil? and
|
24
|
+
!node['content'].empty?
|
23
25
|
}
|
24
26
|
end
|
25
27
|
private :meta_content_type
|
@@ -92,17 +94,22 @@ module Nokogiri
|
|
92
94
|
if string_or_io.respond_to?(:read)
|
93
95
|
url ||= string_or_io.respond_to?(:path) ? string_or_io.path : nil
|
94
96
|
if !encoding
|
95
|
-
#
|
96
|
-
# not
|
97
|
+
# Libxml2's parser has poor support for encoding
|
98
|
+
# detection. First, it does not recognize the HTML5
|
99
|
+
# style meta charset declaration. Secondly, even if it
|
100
|
+
# successfully detects an encoding hint, it does not
|
101
|
+
# re-decode or re-parse the preceding part which may be
|
102
|
+
# garbled.
|
103
|
+
#
|
104
|
+
# EncodingReader aims to perform advanced encoding
|
105
|
+
# detection beyond what Libxml2 does, and to emulate
|
106
|
+
# rewinding of a stream and make Libxml2 redo parsing
|
107
|
+
# from the start when an encoding hint is found.
|
97
108
|
string_or_io = EncodingReader.new(string_or_io)
|
98
109
|
begin
|
99
110
|
return read_io(string_or_io, url, encoding, options.to_i)
|
100
|
-
rescue
|
101
|
-
|
102
|
-
# that it cannot switch encoding well in the middle of
|
103
|
-
# parsing, especially if it has already seen a
|
104
|
-
# non-ASCII character when it finds an encoding hint.
|
105
|
-
encoding = e.encoding
|
111
|
+
rescue EncodingFound => e
|
112
|
+
encoding = e.found_encoding
|
106
113
|
end
|
107
114
|
end
|
108
115
|
return read_io(string_or_io, url, encoding, options.to_i)
|
@@ -111,19 +118,17 @@ module Nokogiri
|
|
111
118
|
# read_memory pukes on empty docs
|
112
119
|
return new if string_or_io.nil? or string_or_io.empty?
|
113
120
|
|
114
|
-
|
115
|
-
encoding = EncodingReader.detect_encoding(string_or_io)
|
116
|
-
end
|
121
|
+
encoding ||= EncodingReader.detect_encoding(string_or_io)
|
117
122
|
|
118
123
|
read_memory(string_or_io, url, encoding, options.to_i)
|
119
124
|
end
|
120
125
|
end
|
121
126
|
|
122
|
-
class
|
123
|
-
attr_reader :
|
127
|
+
class EncodingFound < StandardError # :nodoc:
|
128
|
+
attr_reader :found_encoding
|
124
129
|
|
125
130
|
def initialize(encoding)
|
126
|
-
@
|
131
|
+
@found_encoding = encoding
|
127
132
|
super("encoding found: %s" % encoding)
|
128
133
|
end
|
129
134
|
end
|
@@ -131,57 +136,91 @@ module Nokogiri
|
|
131
136
|
class EncodingReader # :nodoc:
|
132
137
|
class SAXHandler < Nokogiri::XML::SAX::Document # :nodoc:
|
133
138
|
attr_reader :encoding
|
134
|
-
|
135
|
-
def
|
136
|
-
@encoding =
|
137
|
-
|
139
|
+
|
140
|
+
def initialize
|
141
|
+
@encoding = nil
|
142
|
+
super()
|
138
143
|
end
|
139
|
-
|
140
|
-
def
|
141
|
-
|
144
|
+
|
145
|
+
def start_element(name, attrs = [])
|
146
|
+
return unless name == 'meta'
|
147
|
+
attr = Hash[attrs]
|
148
|
+
charset = attr['charset'] and
|
149
|
+
@encoding = charset
|
150
|
+
http_equiv = attr['http-equiv'] and
|
151
|
+
http_equiv.match(/\AContent-Type\z/i) and
|
152
|
+
content = attr['content'] and
|
153
|
+
m = content.match(/;\s*charset\s*=\s*([\w-]+)/) and
|
154
|
+
@encoding = m[1]
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
class JumpSAXHandler < SAXHandler
|
159
|
+
def initialize(jumptag)
|
160
|
+
@jumptag = jumptag
|
161
|
+
super()
|
142
162
|
end
|
143
163
|
|
144
164
|
def start_element(name, attrs = [])
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
when 'meta'
|
149
|
-
attr = Hash[attrs]
|
150
|
-
charset = attr['charset'] and
|
151
|
-
found charset
|
152
|
-
http_equiv = attr['http-equiv'] and
|
153
|
-
http_equiv.match(/\AContent-Type\z/i) and
|
154
|
-
content = attr['content'] and
|
155
|
-
m = content.match(/;\s*charset\s*=\s*([\w-]+)/) and
|
156
|
-
found m[1]
|
157
|
-
end
|
165
|
+
super
|
166
|
+
throw @jumptag, @encoding if @encoding
|
167
|
+
throw @jumptag, nil if name =~ /\A(?:div|h1|img|p|br)\z/
|
158
168
|
end
|
159
169
|
end
|
160
170
|
|
161
171
|
def self.detect_encoding(chunk)
|
172
|
+
if Nokogiri.jruby? && EncodingReader.is_jruby_without_fix?
|
173
|
+
return EncodingReader.detect_encoding_for_jruby_without_fix(chunk)
|
174
|
+
end
|
162
175
|
m = chunk.match(/\A(<\?xml[ \t\r\n]+[^>]*>)/) and
|
163
176
|
return Nokogiri.XML(m[1]).encoding
|
164
177
|
|
165
178
|
if Nokogiri.jruby?
|
166
179
|
m = chunk.match(/(<meta\s)(.*)(charset\s*=\s*([\w-]+))(.*)/i) and
|
167
180
|
return m[4]
|
181
|
+
catch(:encoding_found) {
|
182
|
+
Nokogiri::HTML::SAX::Parser.new(JumpSAXHandler.new(:encoding_found.to_s)).parse(chunk)
|
183
|
+
nil
|
184
|
+
}
|
185
|
+
else
|
186
|
+
handler = SAXHandler.new
|
187
|
+
parser = Nokogiri::HTML::SAX::PushParser.new(handler)
|
188
|
+
parser << chunk rescue Nokogiri::SyntaxError
|
189
|
+
handler.encoding
|
168
190
|
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def self.is_jruby_without_fix?
|
194
|
+
JRUBY_VERSION.split('.').join.to_i < 165
|
195
|
+
end
|
169
196
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
197
|
+
def self.detect_encoding_for_jruby_without_fix(chunk)
|
198
|
+
m = chunk.match(/\A(<\?xml[ \t\r\n]+[^>]*>)/) and
|
199
|
+
return Nokogiri.XML(m[1]).encoding
|
200
|
+
|
201
|
+
m = chunk.match(/(<meta\s)(.*)(charset\s*=\s*([\w-]+))(.*)/i) and
|
202
|
+
return m[4]
|
203
|
+
|
204
|
+
catch(:encoding_found) {
|
205
|
+
Nokogiri::HTML::SAX::Parser.new(JumpSAXHandler.new(:encoding_found.to_s)).parse(chunk)
|
206
|
+
nil
|
174
207
|
}
|
175
|
-
|
176
|
-
|
208
|
+
rescue Nokogiri::SyntaxError, RuntimeError
|
209
|
+
# Ignore parser errors that nokogiri may raise
|
177
210
|
nil
|
178
211
|
end
|
179
212
|
|
180
213
|
def initialize(io)
|
181
214
|
@io = io
|
182
215
|
@firstchunk = nil
|
216
|
+
@encoding_found = nil
|
183
217
|
end
|
184
218
|
|
219
|
+
# This method is used by the C extension so that
|
220
|
+
# Nokogiri::HTML::Document#read_io() does not leak memory when
|
221
|
+
# EncodingFound is raised.
|
222
|
+
attr_reader :encoding_found
|
223
|
+
|
185
224
|
def read(len)
|
186
225
|
# no support for a call without len
|
187
226
|
|
@@ -193,9 +232,10 @@ module Nokogiri
|
|
193
232
|
# achieve advanced encoding detection.
|
194
233
|
if encoding = EncodingReader.detect_encoding(@firstchunk)
|
195
234
|
# The first chunk is stored for the next read in retry.
|
196
|
-
raise
|
235
|
+
raise @encoding_found = EncodingFound.new(encoding)
|
197
236
|
end
|
198
237
|
end
|
238
|
+
@encoding_found = nil
|
199
239
|
|
200
240
|
ret = @firstchunk.slice!(0, len)
|
201
241
|
if (len -= ret.length) > 0
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Nokogiri
|
2
|
+
module HTML
|
3
|
+
module SAX
|
4
|
+
class PushParser
|
5
|
+
def initialize(doc = XML::SAX::Document.new, file_name = nil, encoding = 'UTF-8')
|
6
|
+
@document = doc
|
7
|
+
@encoding = encoding
|
8
|
+
@sax_parser = HTML::SAX::Parser.new(doc, @encoding)
|
9
|
+
|
10
|
+
## Create our push parser context
|
11
|
+
initialize_native(@sax_parser, file_name, @encoding)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/nokogiri/version.rb
CHANGED
data/lib/nokogiri/xml.rb
CHANGED
@@ -35,6 +35,12 @@ module Nokogiri
|
|
35
35
|
end
|
36
36
|
|
37
37
|
module XML
|
38
|
+
# Original C14N 1.0 spec canonicalization
|
39
|
+
XML_C14N_1_0 = 0
|
40
|
+
# Exclusive C14N 1.0 spec canonicalization
|
41
|
+
XML_C14N_EXCLUSIVE_1_0 = 1
|
42
|
+
# C14N 1.1 spec canonicalization
|
43
|
+
XML_C14N_1_1 = 2
|
38
44
|
class << self
|
39
45
|
###
|
40
46
|
# Parse an XML document using the Nokogiri::XML::Reader API. See
|
data/lib/nokogiri/xml/builder.rb
CHANGED
@@ -306,7 +306,13 @@ module Nokogiri
|
|
306
306
|
###
|
307
307
|
# Create a CDATA Node with content of +string+
|
308
308
|
def cdata string
|
309
|
-
insert
|
309
|
+
insert doc.create_cdata(string)
|
310
|
+
end
|
311
|
+
|
312
|
+
###
|
313
|
+
# Create a Comment Node with content of +string+
|
314
|
+
def comment string
|
315
|
+
insert doc.create_comment(string)
|
310
316
|
end
|
311
317
|
|
312
318
|
###
|
@@ -8,6 +8,12 @@ module Nokogiri
|
|
8
8
|
# For searching a Document, see Nokogiri::XML::Node#css and
|
9
9
|
# Nokogiri::XML::Node#xpath
|
10
10
|
class Document < Nokogiri::XML::Node
|
11
|
+
# I'm ignoring unicode characters here.
|
12
|
+
# See http://www.w3.org/TR/REC-xml-names/#ns-decl for more details.
|
13
|
+
NCNAME_START_CHAR = "A-Za-z_"
|
14
|
+
NCNAME_CHAR = NCNAME_START_CHAR + "\\-.0-9"
|
15
|
+
NCNAME_RE = /^xmlns(:[#{NCNAME_START_CHAR}][#{NCNAME_CHAR}]*)?$/
|
16
|
+
|
11
17
|
##
|
12
18
|
# Parse an XML file. +string_or_io+ may be a String, or any object that
|
13
19
|
# responds to _read_ and _close_ such as an IO, or StringIO.
|
@@ -17,20 +23,23 @@ module Nokogiri
|
|
17
23
|
# Nokogiri::XML::ParseOptions::RECOVER. See the constants in
|
18
24
|
# Nokogiri::XML::ParseOptions.
|
19
25
|
def self.parse string_or_io, url = nil, encoding = nil, options = ParseOptions::DEFAULT_XML, &block
|
20
|
-
|
21
26
|
options = Nokogiri::XML::ParseOptions.new(options) if Fixnum === options
|
22
27
|
# Give the options to the user
|
23
28
|
yield options if block_given?
|
24
29
|
|
25
|
-
if string_or_io.respond_to?(:read)
|
30
|
+
doc = if string_or_io.respond_to?(:read)
|
26
31
|
url ||= string_or_io.respond_to?(:path) ? string_or_io.path : nil
|
27
|
-
|
32
|
+
read_io(string_or_io, url, encoding, options.to_i)
|
33
|
+
else
|
34
|
+
# read_memory pukes on empty docs
|
35
|
+
return new if string_or_io.nil? or string_or_io.empty?
|
36
|
+
read_memory(string_or_io, url, encoding, options.to_i)
|
28
37
|
end
|
29
38
|
|
30
|
-
#
|
31
|
-
|
39
|
+
# do xinclude processing
|
40
|
+
doc.do_xinclude(options) if options.xinclude?
|
32
41
|
|
33
|
-
|
42
|
+
return doc
|
34
43
|
end
|
35
44
|
|
36
45
|
# A list of Nokogiri::XML::SyntaxError found when parsing a document
|
@@ -57,7 +66,7 @@ module Nokogiri
|
|
57
66
|
when Hash
|
58
67
|
arg.each { |k,v|
|
59
68
|
key = k.to_s
|
60
|
-
if key =~
|
69
|
+
if key =~ NCNAME_RE
|
61
70
|
ns_name = key.split(":", 2)[1]
|
62
71
|
elm.add_namespace_definition ns_name, v
|
63
72
|
next
|
@@ -71,14 +80,19 @@ module Nokogiri
|
|
71
80
|
elm
|
72
81
|
end
|
73
82
|
|
74
|
-
# Create a
|
75
|
-
def create_text_node
|
76
|
-
Nokogiri::XML::Text.new
|
83
|
+
# Create a Text Node with +string+
|
84
|
+
def create_text_node string, &block
|
85
|
+
Nokogiri::XML::Text.new string.to_s, self, &block
|
86
|
+
end
|
87
|
+
|
88
|
+
# Create a CDATA Node containing +string+
|
89
|
+
def create_cdata string, &block
|
90
|
+
Nokogiri::XML::CDATA.new self, string.to_s, &block
|
77
91
|
end
|
78
92
|
|
79
|
-
# Create a
|
80
|
-
def
|
81
|
-
Nokogiri::XML::
|
93
|
+
# Create a Comment Node containing +string+
|
94
|
+
def create_comment string, &block
|
95
|
+
Nokogiri::XML::Comment.new self, string.to_s, &block
|
82
96
|
end
|
83
97
|
|
84
98
|
# The name of this document. Always returns "document"
|
@@ -194,11 +208,12 @@ module Nokogiri
|
|
194
208
|
undef_method :add_namespace_definition, :attributes
|
195
209
|
undef_method :namespace_definitions, :line, :add_namespace
|
196
210
|
|
197
|
-
def add_child
|
211
|
+
def add_child node_or_tags
|
198
212
|
raise "Document already has a root node" if root
|
199
|
-
|
200
|
-
|
201
|
-
|
213
|
+
node_or_tags = coerce(node_or_tags)
|
214
|
+
if node_or_tags.is_a?(XML::NodeSet)
|
215
|
+
raise "Document cannot have multiple root nodes" if node_or_tags.size > 1
|
216
|
+
super(node_or_tags.first)
|
202
217
|
else
|
203
218
|
super
|
204
219
|
end
|
@@ -11,7 +11,12 @@ module Nokogiri
|
|
11
11
|
return self unless tags
|
12
12
|
|
13
13
|
children = if ctx
|
14
|
-
|
14
|
+
# Fix for issue#490
|
15
|
+
if Nokogiri.jruby?
|
16
|
+
ctx.parse("<root>#{tags}</root>").xpath("/root/node()")
|
17
|
+
else
|
18
|
+
ctx.parse(tags)
|
19
|
+
end
|
15
20
|
else
|
16
21
|
XML::Document.parse("<root>#{tags}</root>") \
|
17
22
|
.xpath("/root/node()")
|
data/lib/nokogiri/xml/node.rb
CHANGED
@@ -255,6 +255,12 @@ module Nokogiri
|
|
255
255
|
get(name.to_s)
|
256
256
|
end
|
257
257
|
|
258
|
+
###
|
259
|
+
# Set the attribute value for the attribute +name+ to +value+
|
260
|
+
def []= name, value
|
261
|
+
set name.to_s, value
|
262
|
+
end
|
263
|
+
|
258
264
|
###
|
259
265
|
# Add +node_or_tags+ as a child of this Node.
|
260
266
|
# +node_or_tags+ can be a Nokogiri::XML::Node, a ::DocumentFragment, a ::NodeSet, or a string containing markup.
|
@@ -291,6 +297,8 @@ module Nokogiri
|
|
291
297
|
#
|
292
298
|
# Also see related method +before+.
|
293
299
|
def add_previous_sibling node_or_tags
|
300
|
+
raise ArgumentError.new("A document may not have multiple root nodes.") if parent.is_a?(XML::Document) && !node_or_tags.is_a?(XML::ProcessingInstruction)
|
301
|
+
|
294
302
|
node_or_tags = coerce(node_or_tags)
|
295
303
|
if node_or_tags.is_a?(XML::NodeSet)
|
296
304
|
if text?
|
@@ -315,6 +323,8 @@ module Nokogiri
|
|
315
323
|
#
|
316
324
|
# Also see related method +after+.
|
317
325
|
def add_next_sibling node_or_tags
|
326
|
+
raise ArgumentError.new("A document may not have multiple root nodes.") if parent.is_a?(XML::Document)
|
327
|
+
|
318
328
|
node_or_tags = coerce(node_or_tags)
|
319
329
|
if node_or_tags.is_a?(XML::NodeSet)
|
320
330
|
if text?
|
@@ -452,9 +462,9 @@ module Nokogiri
|
|
452
462
|
# If you need to distinguish attributes with the same name, with different namespaces
|
453
463
|
# use #attribute_nodes instead.
|
454
464
|
def attributes
|
455
|
-
Hash[
|
465
|
+
Hash[attribute_nodes.map { |node|
|
456
466
|
[node.node_name, node]
|
457
|
-
}
|
467
|
+
}]
|
458
468
|
end
|
459
469
|
|
460
470
|
###
|
@@ -471,9 +481,9 @@ module Nokogiri
|
|
471
481
|
|
472
482
|
###
|
473
483
|
# Iterate over each attribute name and value pair for this Node.
|
474
|
-
def each
|
484
|
+
def each
|
475
485
|
attribute_nodes.each { |node|
|
476
|
-
|
486
|
+
yield [node.node_name, node.value]
|
477
487
|
}
|
478
488
|
end
|
479
489
|
|
@@ -555,7 +565,7 @@ module Nokogiri
|
|
555
565
|
# default namespaces set on ancestor will NOT be, even if self
|
556
566
|
# has no explicit default namespace.
|
557
567
|
def namespaces
|
558
|
-
Hash[
|
568
|
+
Hash[namespace_scopes.map { |nd|
|
559
569
|
key = ['xmlns', nd.prefix].compact.join(':')
|
560
570
|
if RUBY_VERSION >= '1.9' && document.encoding
|
561
571
|
begin
|
@@ -564,7 +574,7 @@ module Nokogiri
|
|
564
574
|
end
|
565
575
|
end
|
566
576
|
[key, nd.href]
|
567
|
-
}
|
577
|
+
}]
|
568
578
|
end
|
569
579
|
|
570
580
|
# Returns true if this is a Comment
|
@@ -766,8 +776,7 @@ module Nokogiri
|
|
766
776
|
#
|
767
777
|
# See Node#write_to for a list of +options+
|
768
778
|
def to_xml options = {}
|
769
|
-
options[:save_with]
|
770
|
-
options[:save_with] = SaveOptions::DEFAULT_XML unless options[:save_with]
|
779
|
+
options[:save_with] ||= SaveOptions::DEFAULT_XML
|
771
780
|
serialize(options)
|
772
781
|
end
|
773
782
|
|
@@ -865,6 +874,28 @@ module Nokogiri
|
|
865
874
|
compare other
|
866
875
|
end
|
867
876
|
|
877
|
+
###
|
878
|
+
# Do xinclude substitution on the subtree below node. If given a block, a
|
879
|
+
# Nokogiri::XML::ParseOptions object initialized from +options+, will be
|
880
|
+
# passed to it, allowing more convenient modification of the parser options.
|
881
|
+
def do_xinclude options = XML::ParseOptions::DEFAULT_XML, &block
|
882
|
+
options = Nokogiri::XML::ParseOptions.new(options) if Fixnum === options
|
883
|
+
|
884
|
+
# give options to user
|
885
|
+
yield options if block_given?
|
886
|
+
|
887
|
+
# call c extension
|
888
|
+
process_xincludes(options.to_i)
|
889
|
+
end
|
890
|
+
|
891
|
+
def canonicalize(mode=XML::XML_C14N_1_0,inclusive_namespaces=nil,with_comments=false)
|
892
|
+
c14n_root = self
|
893
|
+
document.canonicalize(mode, inclusive_namespaces, with_comments) do |node, parent|
|
894
|
+
tn = node.is_a?(XML::Node) ? node : parent
|
895
|
+
tn == c14n_root || tn.ancestors.include?(c14n_root)
|
896
|
+
end
|
897
|
+
end
|
898
|
+
|
868
899
|
private
|
869
900
|
|
870
901
|
def extract_params params # :nodoc:
|
@@ -893,7 +924,7 @@ module Nokogiri
|
|
893
924
|
return data.children if data.is_a?(XML::DocumentFragment)
|
894
925
|
return fragment(data).children if data.is_a?(String)
|
895
926
|
|
896
|
-
if data.is_a?(Document) || !data.is_a?(XML::Node)
|
927
|
+
if data.is_a?(Document) || data.is_a?(XML::Attr) || !data.is_a?(XML::Node)
|
897
928
|
raise ArgumentError, <<-EOERR
|
898
929
|
Requires a Node, NodeSet or String argument, and cannot accept a #{data.class}.
|
899
930
|
(You probably want to select a node from the Document with at() or search(), or create a new Node via Node.new().)
|