nokogiri 1.3.3 → 1.4.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.
- data/CHANGELOG.ja.rdoc +48 -3
- data/CHANGELOG.rdoc +42 -0
- data/Manifest.txt +44 -29
- data/README.ja.rdoc +0 -2
- data/README.rdoc +4 -7
- data/Rakefile +42 -6
- data/bin/nokogiri +7 -5
- data/ext/nokogiri/extconf.rb +5 -21
- data/ext/nokogiri/html_document.c +14 -50
- data/ext/nokogiri/html_element_description.c +7 -7
- data/ext/nokogiri/html_entity_lookup.c +6 -4
- data/ext/nokogiri/html_sax_parser_context.c +92 -0
- data/ext/nokogiri/html_sax_parser_context.h +11 -0
- data/ext/nokogiri/nokogiri.c +9 -3
- data/ext/nokogiri/nokogiri.h +16 -20
- data/ext/nokogiri/xml_attr.c +1 -1
- data/ext/nokogiri/xml_attribute_decl.c +67 -0
- data/ext/nokogiri/xml_attribute_decl.h +9 -0
- data/ext/nokogiri/xml_cdata.c +6 -5
- data/ext/nokogiri/xml_comment.c +3 -2
- data/ext/nokogiri/xml_document.c +93 -23
- data/ext/nokogiri/xml_document_fragment.c +1 -3
- data/ext/nokogiri/xml_dtd.c +63 -6
- data/ext/nokogiri/xml_element_content.c +123 -0
- data/ext/nokogiri/xml_element_content.h +10 -0
- data/ext/nokogiri/xml_element_decl.c +69 -0
- data/ext/nokogiri/xml_element_decl.h +9 -0
- data/ext/nokogiri/xml_entity_decl.c +97 -0
- data/ext/nokogiri/xml_entity_decl.h +10 -0
- data/ext/nokogiri/xml_entity_reference.c +1 -1
- data/ext/nokogiri/xml_io.c +10 -3
- data/ext/nokogiri/xml_io.h +1 -0
- data/ext/nokogiri/xml_namespace.c +2 -2
- data/ext/nokogiri/xml_node.c +139 -34
- data/ext/nokogiri/xml_node.h +0 -1
- data/ext/nokogiri/xml_node_set.c +23 -16
- data/ext/nokogiri/xml_processing_instruction.c +1 -1
- data/ext/nokogiri/xml_reader.c +78 -50
- data/ext/nokogiri/xml_sax_parser.c +109 -168
- data/ext/nokogiri/xml_sax_parser.h +33 -0
- data/ext/nokogiri/xml_sax_parser_context.c +155 -0
- data/ext/nokogiri/xml_sax_parser_context.h +10 -0
- data/ext/nokogiri/xml_sax_push_parser.c +11 -6
- data/ext/nokogiri/xml_syntax_error.c +63 -12
- data/ext/nokogiri/xml_text.c +4 -3
- data/ext/nokogiri/xml_xpath.c +1 -1
- data/ext/nokogiri/xml_xpath_context.c +12 -25
- data/ext/nokogiri/xslt_stylesheet.c +3 -3
- data/lib/nokogiri.rb +4 -4
- data/lib/nokogiri/css/generated_tokenizer.rb +1 -0
- data/lib/nokogiri/css/node.rb +1 -9
- data/lib/nokogiri/css/xpath_visitor.rb +11 -21
- data/lib/nokogiri/ffi/html/document.rb +0 -9
- data/lib/nokogiri/ffi/html/sax/parser_context.rb +38 -0
- data/lib/nokogiri/ffi/io_callbacks.rb +4 -2
- data/lib/nokogiri/ffi/libxml.rb +44 -10
- data/lib/nokogiri/ffi/structs/common_node.rb +1 -1
- data/lib/nokogiri/ffi/structs/xml_attribute.rb +27 -0
- data/lib/nokogiri/ffi/structs/xml_dtd.rb +3 -1
- data/lib/nokogiri/ffi/structs/xml_element.rb +26 -0
- data/lib/nokogiri/ffi/structs/xml_element_content.rb +17 -0
- data/lib/nokogiri/ffi/structs/xml_entity.rb +32 -0
- data/lib/nokogiri/ffi/structs/xml_enumeration.rb +12 -0
- data/lib/nokogiri/ffi/structs/xml_parser_context.rb +19 -0
- data/lib/nokogiri/ffi/structs/xml_sax_push_parser_context.rb +4 -3
- data/lib/nokogiri/ffi/structs/xml_syntax_error.rb +1 -1
- data/lib/nokogiri/ffi/xml/attribute_decl.rb +27 -0
- data/lib/nokogiri/ffi/xml/comment.rb +2 -2
- data/lib/nokogiri/ffi/xml/document.rb +29 -12
- data/lib/nokogiri/ffi/xml/document_fragment.rb +0 -5
- data/lib/nokogiri/ffi/xml/dtd.rb +14 -3
- data/lib/nokogiri/ffi/xml/element_content.rb +43 -0
- data/lib/nokogiri/ffi/xml/element_decl.rb +19 -0
- data/lib/nokogiri/ffi/xml/entity_decl.rb +27 -0
- data/lib/nokogiri/ffi/xml/node.rb +45 -5
- data/lib/nokogiri/ffi/xml/node_set.rb +1 -1
- data/lib/nokogiri/ffi/xml/reader.rb +45 -24
- data/lib/nokogiri/ffi/xml/sax/parser.rb +27 -34
- data/lib/nokogiri/ffi/xml/sax/parser_context.rb +67 -0
- data/lib/nokogiri/ffi/xml/sax/push_parser.rb +5 -4
- data/lib/nokogiri/ffi/xml/syntax_error.rb +31 -16
- data/lib/nokogiri/ffi/xml/text.rb +2 -2
- data/lib/nokogiri/html.rb +1 -0
- data/lib/nokogiri/html/document.rb +39 -24
- data/lib/nokogiri/html/sax/parser.rb +2 -2
- data/lib/nokogiri/html/sax/parser_context.rb +16 -0
- data/lib/nokogiri/version.rb +1 -1
- data/lib/nokogiri/xml.rb +6 -1
- data/lib/nokogiri/xml/attr.rb +5 -0
- data/lib/nokogiri/xml/attribute_decl.rb +18 -0
- data/lib/nokogiri/xml/builder.rb +121 -13
- data/lib/nokogiri/xml/character_data.rb +7 -0
- data/lib/nokogiri/xml/document.rb +43 -29
- data/lib/nokogiri/xml/document_fragment.rb +26 -6
- data/lib/nokogiri/xml/dtd.rb +5 -5
- data/lib/nokogiri/xml/element_content.rb +36 -0
- data/lib/nokogiri/xml/element_decl.rb +13 -0
- data/lib/nokogiri/xml/entity_decl.rb +15 -0
- data/lib/nokogiri/xml/fragment_handler.rb +22 -11
- data/lib/nokogiri/xml/namespace.rb +6 -0
- data/lib/nokogiri/xml/node.rb +33 -15
- data/lib/nokogiri/xml/node_set.rb +66 -44
- data/lib/nokogiri/xml/pp.rb +2 -0
- data/lib/nokogiri/xml/pp/character_data.rb +18 -0
- data/lib/nokogiri/xml/pp/node.rb +56 -0
- data/lib/nokogiri/xml/reader.rb +8 -0
- data/lib/nokogiri/xml/sax.rb +1 -1
- data/lib/nokogiri/xml/sax/document.rb +18 -1
- data/lib/nokogiri/xml/sax/parser.rb +15 -8
- data/lib/nokogiri/xml/sax/parser_context.rb +16 -0
- data/lib/nokogiri/xml/sax/push_parser.rb +0 -3
- data/lib/nokogiri/xml/syntax_error.rb +4 -0
- data/lib/nokogiri/xslt/stylesheet.rb +1 -1
- data/test/css/test_nthiness.rb +1 -1
- data/test/css/test_parser.rb +1 -1
- data/test/css/test_tokenizer.rb +1 -1
- data/test/css/test_xpath_visitor.rb +1 -1
- data/test/ffi/test_document.rb +1 -1
- data/test/files/shift_jis.html +10 -0
- data/test/files/staff.dtd +10 -0
- data/test/helper.rb +12 -3
- data/test/html/sax/test_parser.rb +1 -1
- data/test/html/sax/test_parser_context.rb +48 -0
- data/test/html/test_builder.rb +8 -2
- data/test/html/test_document.rb +23 -1
- data/test/html/test_document_encoding.rb +15 -1
- data/test/html/test_document_fragment.rb +10 -1
- data/test/html/test_element_description.rb +1 -2
- data/test/html/test_named_characters.rb +1 -1
- data/test/html/test_node.rb +61 -1
- data/test/html/test_node_encoding.rb +27 -0
- data/test/test_convert_xpath.rb +1 -3
- data/test/test_css_cache.rb +1 -1
- data/test/test_gc.rb +1 -1
- data/test/test_memory_leak.rb +1 -1
- data/test/test_nokogiri.rb +3 -3
- data/test/test_reader.rb +29 -1
- data/test/test_xslt_transforms.rb +1 -1
- data/test/xml/node/test_save_options.rb +1 -1
- data/test/xml/node/test_subclass.rb +1 -1
- data/test/xml/sax/test_parser.rb +64 -3
- data/test/xml/sax/test_parser_context.rb +56 -0
- data/test/xml/sax/test_push_parser.rb +11 -1
- data/test/xml/test_attr.rb +1 -1
- data/test/xml/test_attribute_decl.rb +82 -0
- data/test/xml/test_builder.rb +95 -1
- data/test/xml/test_cdata.rb +1 -1
- data/test/xml/test_comment.rb +7 -1
- data/test/xml/test_document.rb +147 -6
- data/test/xml/test_document_encoding.rb +1 -1
- data/test/xml/test_document_fragment.rb +55 -5
- data/test/xml/test_dtd.rb +40 -5
- data/test/xml/test_dtd_encoding.rb +3 -1
- data/test/xml/test_element_content.rb +56 -0
- data/test/xml/test_element_decl.rb +73 -0
- data/test/xml/test_entity_decl.rb +83 -0
- data/test/xml/test_entity_reference.rb +1 -1
- data/test/xml/test_namespace.rb +21 -1
- data/test/xml/test_node.rb +70 -4
- data/test/xml/test_node_attributes.rb +1 -1
- data/test/xml/test_node_encoding.rb +1 -1
- data/test/xml/test_node_set.rb +136 -2
- data/test/xml/test_parse_options.rb +1 -1
- data/test/xml/test_processing_instruction.rb +1 -1
- data/test/xml/test_reader_encoding.rb +1 -1
- data/test/xml/test_relax_ng.rb +1 -1
- data/test/xml/test_schema.rb +1 -1
- data/test/xml/test_syntax_error.rb +27 -0
- data/test/xml/test_text.rb +13 -1
- data/test/xml/test_unparented_node.rb +1 -1
- data/test/xml/test_xpath.rb +1 -1
- metadata +57 -40
- data/ext/nokogiri/html_sax_parser.c +0 -57
- data/ext/nokogiri/html_sax_parser.h +0 -11
- data/lib/action-nokogiri.rb +0 -38
- data/lib/nokogiri/decorators.rb +0 -2
- data/lib/nokogiri/decorators/hpricot.rb +0 -3
- data/lib/nokogiri/decorators/hpricot/node.rb +0 -56
- data/lib/nokogiri/decorators/hpricot/node_set.rb +0 -54
- data/lib/nokogiri/decorators/hpricot/xpath_visitor.rb +0 -30
- data/lib/nokogiri/ffi/html/sax/parser.rb +0 -21
- data/lib/nokogiri/hpricot.rb +0 -92
- data/lib/nokogiri/xml/entity_declaration.rb +0 -11
- data/lib/nokogiri/xml/sax/legacy_handlers.rb +0 -65
- data/test/hpricot/files/basic.xhtml +0 -17
- data/test/hpricot/files/boingboing.html +0 -2266
- data/test/hpricot/files/cy0.html +0 -3653
- data/test/hpricot/files/immob.html +0 -400
- data/test/hpricot/files/pace_application.html +0 -1320
- data/test/hpricot/files/tenderlove.html +0 -16
- data/test/hpricot/files/uswebgen.html +0 -220
- data/test/hpricot/files/utf8.html +0 -1054
- data/test/hpricot/files/week9.html +0 -1723
- data/test/hpricot/files/why.xml +0 -19
- data/test/hpricot/load_files.rb +0 -11
- data/test/hpricot/test_alter.rb +0 -68
- data/test/hpricot/test_builder.rb +0 -20
- data/test/hpricot/test_parser.rb +0 -350
- data/test/hpricot/test_paths.rb +0 -15
- data/test/hpricot/test_preserved.rb +0 -77
- data/test/hpricot/test_xml.rb +0 -30
@@ -3,12 +3,15 @@ module Nokogiri
|
|
3
3
|
class DocumentFragment < Nokogiri::XML::Node
|
4
4
|
def initialize document, tags=nil
|
5
5
|
if tags
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
if self.kind_of?(Nokogiri::HTML::DocumentFragment)
|
7
|
+
HTML::SAX::Parser.new(FragmentHandler.new(self, tags)).parse(tags)
|
8
|
+
else
|
9
|
+
wrapped = "<div>#{tags.strip}</div>"
|
10
|
+
XML::SAX::Parser.new(FragmentHandler.new(self, wrapped)).parse(wrapped)
|
11
|
+
div = self.child
|
12
|
+
div.children.each { |child| child.parent = self }
|
13
|
+
div.unlink
|
14
|
+
end
|
12
15
|
end
|
13
16
|
end
|
14
17
|
|
@@ -18,22 +21,39 @@ module Nokogiri
|
|
18
21
|
'#document-fragment'
|
19
22
|
end
|
20
23
|
|
24
|
+
###
|
25
|
+
# Convert this DocumentFragment to a string
|
21
26
|
def to_s
|
22
27
|
children.to_s
|
23
28
|
end
|
24
29
|
|
30
|
+
###
|
31
|
+
# Convert this DocumentFragment to html
|
32
|
+
# See Nokogiri::XML::NodeSet#to_html
|
25
33
|
def to_html *args
|
26
34
|
children.to_html(*args)
|
27
35
|
end
|
28
36
|
|
37
|
+
###
|
38
|
+
# Convert this DocumentFragment to xhtml
|
39
|
+
# See Nokogiri::XML::NodeSet#to_xhtml
|
29
40
|
def to_xhtml *args
|
30
41
|
children.to_xhtml(*args)
|
31
42
|
end
|
32
43
|
|
44
|
+
###
|
45
|
+
# Convert this DocumentFragment to xml
|
46
|
+
# See Nokogiri::XML::NodeSet#to_xml
|
33
47
|
def to_xml *args
|
34
48
|
children.to_xml(*args)
|
35
49
|
end
|
36
50
|
|
51
|
+
###
|
52
|
+
# Search this fragment. See Nokogiri::XML::Node#css
|
53
|
+
def css *args
|
54
|
+
children.css(*args)
|
55
|
+
end
|
56
|
+
|
37
57
|
alias :serialize :to_s
|
38
58
|
|
39
59
|
class << self
|
data/lib/nokogiri/xml/dtd.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
module Nokogiri
|
2
2
|
module XML
|
3
3
|
class DTD < Nokogiri::XML::Node
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
undef_method :attribute_nodes
|
5
|
+
undef_method :content
|
6
|
+
undef_method :namespace
|
7
|
+
undef_method :namespace_definitions
|
8
|
+
undef_method :line
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Nokogiri
|
2
|
+
module XML
|
3
|
+
###
|
4
|
+
# Represents the allowed content in an Element Declaration inside a DTD:
|
5
|
+
#
|
6
|
+
# <?xml version="1.0"?><?TEST-STYLE PIDATA?>
|
7
|
+
# <!DOCTYPE staff SYSTEM "staff.dtd" [
|
8
|
+
# <!ELEMENT div1 (head, (p | list | note)*, div2*)>
|
9
|
+
# ]>
|
10
|
+
# </root>
|
11
|
+
#
|
12
|
+
# ElementContent represents the tree inside the <!ELEMENT> tag shown above
|
13
|
+
# that lists the possible content for the div1 tag.
|
14
|
+
class ElementContent
|
15
|
+
# Possible definitions of type
|
16
|
+
PCDATA = 1
|
17
|
+
ELEMENT = 2
|
18
|
+
SEQ = 3
|
19
|
+
OR = 4
|
20
|
+
|
21
|
+
# Possible content occurrences
|
22
|
+
ONCE = 1
|
23
|
+
OPT = 2
|
24
|
+
MULT = 3
|
25
|
+
PLUS = 4
|
26
|
+
|
27
|
+
attr_reader :document
|
28
|
+
|
29
|
+
###
|
30
|
+
# Get the children of this ElementContent node
|
31
|
+
def children
|
32
|
+
[c1, c2].compact
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Nokogiri
|
2
|
+
module XML
|
3
|
+
class ElementDecl < Nokogiri::XML::Node
|
4
|
+
undef_method :namespace
|
5
|
+
undef_method :namespace_definitions
|
6
|
+
undef_method :line
|
7
|
+
|
8
|
+
def inspect
|
9
|
+
"#<#{self.class.name}:#{sprintf("0x%x", object_id)} #{to_s.inspect}>"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Nokogiri
|
2
|
+
module XML
|
3
|
+
class EntityDecl < Nokogiri::XML::Node
|
4
|
+
undef_method :attribute_nodes
|
5
|
+
undef_method :attributes
|
6
|
+
undef_method :namespace
|
7
|
+
undef_method :namespace_definitions
|
8
|
+
undef_method :line
|
9
|
+
|
10
|
+
def inspect
|
11
|
+
"#<#{self.class.name}:#{sprintf("0x%x", object_id)} #{to_s.inspect}>"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,16 +1,14 @@
|
|
1
1
|
module Nokogiri
|
2
2
|
module XML
|
3
3
|
class FragmentHandler < Nokogiri::XML::SAX::Document # :nodoc:
|
4
|
+
QNAME_REGEX = /(.*):(.*)/
|
5
|
+
|
4
6
|
def initialize node, original_html
|
5
7
|
@doc_started = false
|
6
8
|
@document = node.document
|
7
9
|
@stack = [node]
|
8
|
-
@
|
9
|
-
|
10
|
-
else
|
11
|
-
Nokogiri::XML::DocumentFragment
|
12
|
-
end
|
13
|
-
#
|
10
|
+
@html_eh = node.kind_of? HTML::DocumentFragment
|
11
|
+
|
14
12
|
# the regexes used in start_element() and characters() anchor at
|
15
13
|
# start-of-line, but we really only want them to anchor at
|
16
14
|
# start-of-doc. so let's only save up to the first newline.
|
@@ -24,31 +22,44 @@ module Nokogiri
|
|
24
22
|
end
|
25
23
|
|
26
24
|
def start_element name, attrs = []
|
27
|
-
regex =
|
28
|
-
|
25
|
+
regex = @html_eh ? %r{^\s*<#{Regexp.escape(name)}}i :
|
26
|
+
%r{^\s*<#{Regexp.escape(name)}}
|
27
|
+
|
29
28
|
@doc_started = true if @original_html =~ regex
|
30
29
|
return unless @doc_started
|
31
30
|
|
31
|
+
if match = name.match(QNAME_REGEX)
|
32
|
+
prefix, name = match[1], match[2]
|
33
|
+
ns = @document.root.namespace_definitions.detect { |x|
|
34
|
+
x.prefix == prefix
|
35
|
+
}
|
36
|
+
else
|
37
|
+
ns = nil
|
38
|
+
end
|
39
|
+
|
32
40
|
node = Element.new(name, @document)
|
33
41
|
attrs << "" unless (attrs.length % 2) == 0
|
34
42
|
Hash[*attrs].each do |k,v|
|
35
43
|
node[k] = v
|
36
44
|
end
|
45
|
+
|
46
|
+
node.namespace = ns if ns
|
47
|
+
|
37
48
|
@stack.last << node
|
38
49
|
@stack << node
|
39
50
|
end
|
40
51
|
|
41
52
|
def characters string
|
42
53
|
@doc_started = true if @original_html.strip =~ %r{^\s*#{Regexp.escape(string.strip)}}
|
43
|
-
@stack.last <<
|
54
|
+
@stack.last << Text.new(string, @document)
|
44
55
|
end
|
45
56
|
|
46
57
|
def comment string
|
47
|
-
@stack.last <<
|
58
|
+
@stack.last << Comment.new(@document, string)
|
48
59
|
end
|
49
60
|
|
50
61
|
def cdata_block string
|
51
|
-
@stack.last <<
|
62
|
+
@stack.last << CDATA.new(@document, string)
|
52
63
|
end
|
53
64
|
|
54
65
|
def end_element name
|
data/lib/nokogiri/xml/node.rb
CHANGED
@@ -34,6 +34,8 @@ module Nokogiri
|
|
34
34
|
#
|
35
35
|
# You may search this node's subtree using Node#xpath and Node#css
|
36
36
|
class Node
|
37
|
+
include Nokogiri::XML::PP::Node
|
38
|
+
|
37
39
|
# Element node type, see Nokogiri::XML::Node#element?
|
38
40
|
ELEMENT_NODE = 1
|
39
41
|
# Attribute node type
|
@@ -198,6 +200,24 @@ module Nokogiri
|
|
198
200
|
end
|
199
201
|
alias :% :at
|
200
202
|
|
203
|
+
##
|
204
|
+
# Search this node for the first occurrence of XPath +paths+.
|
205
|
+
# Equivalent to <tt>xpath(paths).first</tt>
|
206
|
+
# See Node#xpath for more information.
|
207
|
+
#
|
208
|
+
def at_xpath *paths
|
209
|
+
xpath(*paths).first
|
210
|
+
end
|
211
|
+
|
212
|
+
##
|
213
|
+
# Search this node for the first occurrence of CSS +rules+.
|
214
|
+
# Equivalent to <tt>css(rules).first</tt>
|
215
|
+
# See Node#css for more information.
|
216
|
+
#
|
217
|
+
def at_css *rules
|
218
|
+
css(*rules).first
|
219
|
+
end
|
220
|
+
|
201
221
|
###
|
202
222
|
# Get the attribute value for the attribute +name+
|
203
223
|
def [] name
|
@@ -388,8 +408,8 @@ module Nokogiri
|
|
388
408
|
end
|
389
409
|
|
390
410
|
# Get the inner_html for this node's Node#children
|
391
|
-
def inner_html
|
392
|
-
children.map { |x| x.to_html }.join
|
411
|
+
def inner_html *args
|
412
|
+
children.map { |x| x.to_html(*args) }.join
|
393
413
|
end
|
394
414
|
|
395
415
|
# Get the path to this node as a CSS expression
|
@@ -399,14 +419,6 @@ module Nokogiri
|
|
399
419
|
}.compact.join(' > ')
|
400
420
|
end
|
401
421
|
|
402
|
-
# recursively get all namespaces from this node and its subtree
|
403
|
-
def collect_namespaces
|
404
|
-
# TODO: print warning message if a prefix refers to more than one URI in the document?
|
405
|
-
ns = {}
|
406
|
-
traverse {|j| ns.merge!(j.namespaces)}
|
407
|
-
ns
|
408
|
-
end
|
409
|
-
|
410
422
|
###
|
411
423
|
# Get a list of ancestor Node for this Node. If +selector+ is given,
|
412
424
|
# the ancestors must match +selector+
|
@@ -461,7 +473,8 @@ module Nokogiri
|
|
461
473
|
end
|
462
474
|
|
463
475
|
####
|
464
|
-
#
|
476
|
+
# +replace+ this Node with the +new_node+ in the Document. The new node
|
477
|
+
# must be a Nokogiri::XML::Node or a non-empty String
|
465
478
|
def replace new_node
|
466
479
|
if new_node.is_a?(Document) || !new_node.is_a?(XML::Node)
|
467
480
|
raise ArgumentError, <<-EOERR
|
@@ -500,9 +513,11 @@ Node.replace requires a Node argument, and cannot accept a Document.
|
|
500
513
|
:save_with => args[1] || SaveOptions::FORMAT
|
501
514
|
}
|
502
515
|
|
516
|
+
encoding = options[:encoding] || document.encoding
|
517
|
+
|
503
518
|
outstring = ""
|
504
|
-
if
|
505
|
-
outstring.force_encoding(Encoding.find(
|
519
|
+
if encoding && outstring.respond_to?(:force_encoding)
|
520
|
+
outstring.force_encoding(Encoding.find(encoding))
|
506
521
|
end
|
507
522
|
io = StringIO.new(outstring)
|
508
523
|
write_to io, options, &block
|
@@ -640,8 +655,11 @@ Node.replace requires a Node argument, and cannot accept a Document.
|
|
640
655
|
return nil unless document == other.document
|
641
656
|
compare other
|
642
657
|
end
|
658
|
+
|
659
|
+
private
|
660
|
+
def inspect_attributes
|
661
|
+
[:name, :namespace, :attribute_nodes, :children]
|
662
|
+
end
|
643
663
|
end
|
644
664
|
end
|
645
665
|
end
|
646
|
-
|
647
|
-
class Nokogiri::XML::Element < Nokogiri::XML::Node ; end
|
@@ -68,16 +68,21 @@ module Nokogiri
|
|
68
68
|
# For more information see Nokogiri::XML::Node#css and
|
69
69
|
# Nokogiri::XML::Node#xpath
|
70
70
|
def search *paths
|
71
|
-
|
72
|
-
|
71
|
+
handler = ![
|
72
|
+
Hash, String, Symbol
|
73
|
+
].include?(paths.last.class) ? paths.pop : nil
|
74
|
+
|
75
|
+
ns = paths.last.is_a?(Hash) ? paths.pop : nil
|
73
76
|
|
74
77
|
sub_set = NodeSet.new(document)
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
78
|
+
|
79
|
+
paths.each do |path|
|
80
|
+
sub_set += send(
|
81
|
+
path =~ /^(\.\/|\/)/ ? :xpath : :css,
|
82
|
+
*(paths + [ns, handler]).compact
|
83
|
+
)
|
80
84
|
end
|
85
|
+
|
81
86
|
document.decorate(sub_set)
|
82
87
|
sub_set
|
83
88
|
end
|
@@ -88,19 +93,26 @@ module Nokogiri
|
|
88
93
|
#
|
89
94
|
# For more information see Nokogiri::XML::Node#css
|
90
95
|
def css *paths
|
91
|
-
|
92
|
-
|
96
|
+
handler = ![
|
97
|
+
Hash, String, Symbol
|
98
|
+
].include?(paths.last.class) ? paths.pop : nil
|
99
|
+
|
100
|
+
ns = paths.last.is_a?(Hash) ? paths.pop : nil
|
93
101
|
|
94
102
|
sub_set = NodeSet.new(document)
|
95
103
|
|
96
|
-
xpaths = paths.map { |rule|
|
97
|
-
[
|
98
|
-
CSS.xpath_for(rule.to_s, :prefix => ".//", :ns => ns),
|
99
|
-
CSS.xpath_for(rule.to_s, :prefix => "self::", :ns => ns)
|
100
|
-
].join(' | ')
|
101
|
-
}
|
102
104
|
each do |node|
|
103
|
-
|
105
|
+
doc = node.document
|
106
|
+
search_ns = ns || doc.root ? doc.root.namespaces : {}
|
107
|
+
|
108
|
+
xpaths = paths.map { |rule|
|
109
|
+
[
|
110
|
+
CSS.xpath_for(rule.to_s, :prefix => ".//", :ns => search_ns),
|
111
|
+
CSS.xpath_for(rule.to_s, :prefix => "self::", :ns => search_ns)
|
112
|
+
].join(' | ')
|
113
|
+
}
|
114
|
+
|
115
|
+
sub_set += node.xpath(*(xpaths + [search_ns, handler].compact))
|
104
116
|
end
|
105
117
|
document.decorate(sub_set)
|
106
118
|
sub_set
|
@@ -111,12 +123,15 @@ module Nokogiri
|
|
111
123
|
#
|
112
124
|
# For more information see Nokogiri::XML::Node#xpath
|
113
125
|
def xpath *paths
|
114
|
-
|
115
|
-
|
126
|
+
handler = ![
|
127
|
+
Hash, String, Symbol
|
128
|
+
].include?(paths.last.class) ? paths.pop : nil
|
129
|
+
|
130
|
+
ns = paths.last.is_a?(Hash) ? paths.pop : nil
|
116
131
|
|
117
132
|
sub_set = NodeSet.new(document)
|
118
133
|
each do |node|
|
119
|
-
sub_set += node.xpath(*(paths + [ns]))
|
134
|
+
sub_set += node.xpath(*(paths + [ns, handler].compact))
|
120
135
|
end
|
121
136
|
document.decorate(sub_set)
|
122
137
|
sub_set
|
@@ -135,23 +150,27 @@ module Nokogiri
|
|
135
150
|
# Append the class attribute +name+ to all Node objects in the NodeSet.
|
136
151
|
def add_class name
|
137
152
|
each do |el|
|
138
|
-
|
139
|
-
|
140
|
-
el.set_attribute('class', classes.push(name).uniq.join(" "))
|
153
|
+
classes = el['class'].to_s.split(/\s+/)
|
154
|
+
el['class'] = classes.push(name).uniq.join " "
|
141
155
|
end
|
142
156
|
self
|
143
157
|
end
|
144
158
|
|
145
159
|
###
|
146
160
|
# Remove the class attribute +name+ from all Node objects in the NodeSet.
|
161
|
+
# If +name+ is nil, remove the class attribute from all Nodes in the
|
162
|
+
# NodeSet.
|
147
163
|
def remove_class name = nil
|
148
164
|
each do |el|
|
149
|
-
next unless el.respond_to? :get_attribute
|
150
165
|
if name
|
151
|
-
classes = el
|
152
|
-
|
166
|
+
classes = el['class'].to_s.split(/\s+/)
|
167
|
+
if classes.empty?
|
168
|
+
el.delete 'class'
|
169
|
+
else
|
170
|
+
el['class'] = (classes - [name]).uniq.join " "
|
171
|
+
end
|
153
172
|
else
|
154
|
-
el.
|
173
|
+
el.delete "class"
|
155
174
|
end
|
156
175
|
end
|
157
176
|
self
|
@@ -161,28 +180,23 @@ module Nokogiri
|
|
161
180
|
# Set the attribute +key+ to +value+ or the return value of +blk+
|
162
181
|
# on all Node objects in the NodeSet.
|
163
182
|
def attr key, value = nil, &blk
|
164
|
-
|
165
|
-
|
166
|
-
el.set_attribute(key, value || blk[el])
|
167
|
-
end
|
168
|
-
return self
|
169
|
-
end
|
170
|
-
if key.is_a? Hash
|
171
|
-
key.each { |k,v| self.attr(k,v) }
|
172
|
-
return self
|
173
|
-
else
|
174
|
-
return self[0].get_attribute(key)
|
183
|
+
unless Hash === key || key && (value || blk)
|
184
|
+
return first.attribute(key)
|
175
185
|
end
|
186
|
+
|
187
|
+
hash = key.is_a?(Hash) ? key : { key => value }
|
188
|
+
|
189
|
+
hash.each { |k,v| each { |el| el[k] = v || blk[el] } }
|
190
|
+
|
191
|
+
self
|
176
192
|
end
|
177
|
-
|
193
|
+
alias :set :attr
|
194
|
+
alias :attribute :attr
|
178
195
|
|
179
196
|
###
|
180
197
|
# Remove the attributed named +name+ from all Node objects in the NodeSet
|
181
198
|
def remove_attr name
|
182
|
-
each
|
183
|
-
next unless el.respond_to? :remove_attribute
|
184
|
-
el.remove_attribute(name)
|
185
|
-
end
|
199
|
+
each { |el| el.delete name }
|
186
200
|
self
|
187
201
|
end
|
188
202
|
|
@@ -212,7 +226,7 @@ module Nokogiri
|
|
212
226
|
def wrap(html, &blk)
|
213
227
|
each do |j|
|
214
228
|
new_parent = Nokogiri.make(html, &blk)
|
215
|
-
j.
|
229
|
+
j.add_next_sibling(new_parent)
|
216
230
|
new_parent.add_child(j)
|
217
231
|
end
|
218
232
|
self
|
@@ -275,11 +289,19 @@ module Nokogiri
|
|
275
289
|
end
|
276
290
|
|
277
291
|
###
|
278
|
-
# Returns a new NodeSet containing all the children of all the nodes in
|
292
|
+
# Returns a new NodeSet containing all the children of all the nodes in
|
293
|
+
# the NodeSet
|
279
294
|
def children
|
280
295
|
inject(NodeSet.new(document)) { |set, node| set += node.children }
|
281
296
|
end
|
282
297
|
|
298
|
+
###
|
299
|
+
# Return a nicely formated string representation
|
300
|
+
def inspect
|
301
|
+
"[#{map { |c| c.inspect }.join ', '}]"
|
302
|
+
end
|
303
|
+
|
304
|
+
alias :+ :|
|
283
305
|
end
|
284
306
|
end
|
285
307
|
end
|