nokogiri 1.2.1 → 1.2.2
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/.autotest +15 -0
- data/{History.ja.txt → CHANGELOG.ja.rdoc} +30 -2
- data/{History.txt → CHANGELOG.rdoc} +28 -2
- data/Manifest.txt +13 -7
- data/{README.ja.txt → README.ja.rdoc} +3 -1
- data/{README.txt → README.rdoc} +7 -1
- data/Rakefile +8 -25
- data/ext/nokogiri/extconf.rb +4 -4
- data/ext/nokogiri/html_entity_lookup.c +30 -0
- data/ext/nokogiri/html_entity_lookup.h +8 -0
- data/ext/nokogiri/native.c +22 -0
- data/ext/nokogiri/native.h +27 -4
- data/ext/nokogiri/xml_document.c +31 -4
- data/ext/nokogiri/xml_document.h +11 -0
- data/ext/nokogiri/xml_document_fragment.c +1 -1
- data/ext/nokogiri/xml_node.c +71 -58
- data/ext/nokogiri/xml_node_set.c +26 -0
- data/ext/nokogiri/xml_reader.c +4 -2
- data/ext/nokogiri/xml_sax_parser.c +0 -37
- data/ext/nokogiri/xml_sax_push_parser.c +2 -2
- data/ext/nokogiri/xml_xpath_context.c +34 -7
- data/lib/nokogiri.rb +25 -0
- data/lib/nokogiri/css/generated_tokenizer.rb +2 -2
- data/lib/nokogiri/css/node.rb +2 -0
- data/lib/nokogiri/css/parser.rb +3 -2
- data/lib/nokogiri/html.rb +9 -52
- data/lib/nokogiri/html/document.rb +2 -0
- data/lib/nokogiri/html/entity_lookup.rb +11 -0
- data/lib/nokogiri/version.rb +1 -1
- data/lib/nokogiri/xml.rb +1 -2
- data/lib/nokogiri/xml/builder.rb +18 -5
- data/lib/nokogiri/xml/document.rb +15 -1
- data/lib/nokogiri/xml/fragment_handler.rb +34 -0
- data/lib/nokogiri/xml/node.rb +104 -29
- data/lib/nokogiri/xml/node_set.rb +12 -10
- data/lib/nokogiri/xml/sax/parser.rb +3 -3
- data/lib/xsd/xmlparser/nokogiri.rb +53 -0
- data/tasks/test.rb +7 -5
- data/test/css/test_nthiness.rb +1 -0
- data/test/css/test_parser.rb +1 -0
- data/test/css/test_tokenizer.rb +1 -0
- data/test/css/test_xpath_visitor.rb +1 -0
- data/test/helper.rb +4 -0
- data/test/hpricot/test_alter.rb +1 -0
- data/test/html/sax/test_parser.rb +13 -0
- data/test/html/test_builder.rb +21 -0
- data/test/html/test_document.rb +36 -0
- data/test/html/test_document_encoding.rb +46 -0
- data/test/html/test_named_characters.rb +14 -0
- data/test/html/test_node.rb +80 -0
- data/test/test_convert_xpath.rb +1 -0
- data/test/test_css_cache.rb +1 -0
- data/test/test_nokogiri.rb +8 -0
- data/test/xml/sax/test_parser.rb +6 -0
- data/test/xml/sax/test_push_parser.rb +1 -0
- data/test/xml/test_builder.rb +9 -0
- data/test/xml/test_cdata.rb +1 -0
- data/test/xml/test_comment.rb +1 -0
- data/test/xml/test_document.rb +58 -0
- data/test/xml/test_document_encoding.rb +15 -14
- data/test/xml/test_document_fragment.rb +6 -0
- data/test/xml/test_dtd.rb +1 -0
- data/test/xml/test_dtd_encoding.rb +1 -0
- data/test/xml/test_entity_reference.rb +1 -0
- data/test/xml/test_node.rb +52 -4
- data/test/xml/test_node_encoding.rb +1 -0
- data/test/xml/test_node_set.rb +21 -1
- data/test/xml/test_processing_instruction.rb +1 -0
- data/test/xml/test_reader_encoding.rb +1 -0
- data/test/xml/test_unparented_node.rb +381 -0
- data/test/xml/test_xpath.rb +1 -0
- metadata +34 -16
- data/lib/nokogiri/xml/after_handler.rb +0 -18
- data/lib/nokogiri/xml/before_handler.rb +0 -33
- data/vendor/hoe.rb +0 -1020
data/lib/nokogiri/css/node.rb
CHANGED
@@ -11,6 +11,8 @@ module Nokogiri
|
|
11
11
|
visitor.send(:"visit_#{type.to_s.downcase}", self)
|
12
12
|
end
|
13
13
|
|
14
|
+
###
|
15
|
+
# Convert this CSS node to xpath with +prefix+ using +visitor+
|
14
16
|
def to_xpath prefix = '//', visitor = XPathVisitor.new
|
15
17
|
self.preprocess!
|
16
18
|
prefix + visitor.accept(self)
|
data/lib/nokogiri/css/parser.rb
CHANGED
@@ -52,14 +52,15 @@ module Nokogiri
|
|
52
52
|
alias :parse :scan_str
|
53
53
|
|
54
54
|
def xpath_for string, options={}
|
55
|
-
|
55
|
+
key = string + options[:ns].to_s
|
56
|
+
v = self.class[key]
|
56
57
|
return v if v
|
57
58
|
|
58
59
|
args = [
|
59
60
|
options[:prefix] || '//',
|
60
61
|
options[:visitor] || XPathVisitor.new
|
61
62
|
]
|
62
|
-
self.class[
|
63
|
+
self.class[key] = parse(string).map { |ast|
|
63
64
|
ast.to_xpath(*args)
|
64
65
|
}
|
65
66
|
end
|
data/lib/nokogiri/html.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'nokogiri/html/entity_lookup'
|
1
2
|
require 'nokogiri/html/document'
|
2
3
|
require 'nokogiri/html/sax/parser'
|
3
4
|
|
@@ -28,6 +29,10 @@ module Nokogiri
|
|
28
29
|
###
|
29
30
|
# Parse HTML. See Nokogiri.HTML.
|
30
31
|
def parse string_or_io, url = nil, encoding = nil, options = 2145
|
32
|
+
if string_or_io.respond_to?(:encoding)
|
33
|
+
encoding ||= string_or_io.encoding.name
|
34
|
+
end
|
35
|
+
|
31
36
|
if string_or_io.respond_to?(:read)
|
32
37
|
url ||= string_or_io.respond_to?(:path) ? string_or_io.path : nil
|
33
38
|
return Document.read_io(string_or_io, url, encoding, options)
|
@@ -43,6 +48,9 @@ module Nokogiri
|
|
43
48
|
fragment = XML::DocumentFragment.new(doc)
|
44
49
|
finder = lambda { |c, f|
|
45
50
|
c.each do |child|
|
51
|
+
if string == child.content && child.name == 'text'
|
52
|
+
fragment.add_child(child)
|
53
|
+
end
|
46
54
|
fragment.add_child(child) if string =~ /<#{child.name}/
|
47
55
|
end
|
48
56
|
return fragment if fragment.children.length > 0
|
@@ -55,57 +63,6 @@ module Nokogiri
|
|
55
63
|
fragment
|
56
64
|
end
|
57
65
|
end
|
58
|
-
|
59
|
-
NamedCharacters =
|
60
|
-
{"AElig"=>198, "Aacute"=>193, "Acirc"=>194, "Agrave"=>192, "Alpha"=>913,
|
61
|
-
"Aring"=>197, "Atilde"=>195, "Auml"=>196, "Beta"=>914, "Ccedil"=>199,
|
62
|
-
"Chi"=>935, "Dagger"=>8225, "Delta"=>916, "ETH"=>208, "Eacute"=>201,
|
63
|
-
"Ecirc"=>202, "Egrave"=>200, "Epsilon"=>917, "Eta"=>919, "Euml"=>203,
|
64
|
-
"Gamma"=>915, "Iacute"=>205, "Icirc"=>206, "Igrave"=>204, "Iota"=>921,
|
65
|
-
"Iuml"=>207, "Kappa"=>922, "Lambda"=>923, "Mu"=>924, "Ntilde"=>209, "Nu"=>925,
|
66
|
-
"OElig"=>338, "Oacute"=>211, "Ocirc"=>212, "Ograve"=>210, "Omega"=>937,
|
67
|
-
"Omicron"=>927, "Oslash"=>216, "Otilde"=>213, "Ouml"=>214, "Phi"=>934,
|
68
|
-
"Pi"=>928, "Prime"=>8243, "Psi"=>936, "Rho"=>929, "Scaron"=>352, "Sigma"=>931,
|
69
|
-
"THORN"=>222, "Tau"=>932, "Theta"=>920, "Uacute"=>218, "Ucirc"=>219,
|
70
|
-
"Ugrave"=>217, "Upsilon"=>933, "Uuml"=>220, "Xi"=>926, "Yacute"=>221,
|
71
|
-
"Yuml"=>376, "Zeta"=>918, "aacute"=>225, "acirc"=>226, "acute"=>180,
|
72
|
-
"aelig"=>230, "agrave"=>224, "alefsym"=>8501, "alpha"=>945, "amp"=>38,
|
73
|
-
"and"=>8743, "ang"=>8736, "apos"=>39, "aring"=>229, "asymp"=>8776,
|
74
|
-
"atilde"=>227, "auml"=>228, "bdquo"=>8222, "beta"=>946, "brvbar"=>166,
|
75
|
-
"bull"=>8226, "cap"=>8745, "ccedil"=>231, "cedil"=>184, "cent"=>162,
|
76
|
-
"chi"=>967, "circ"=>710, "clubs"=>9827, "cong"=>8773, "copy"=>169,
|
77
|
-
"crarr"=>8629, "cup"=>8746, "curren"=>164, "dArr"=>8659, "dagger"=>8224,
|
78
|
-
"darr"=>8595, "deg"=>176, "delta"=>948, "diams"=>9830, "divide"=>247,
|
79
|
-
"eacute"=>233, "ecirc"=>234, "egrave"=>232, "empty"=>8709, "emsp"=>8195,
|
80
|
-
"ensp"=>8194, "epsilon"=>949, "equiv"=>8801, "eta"=>951, "eth"=>240,
|
81
|
-
"euml"=>235, "euro"=>8364, "exist"=>8707, "fnof"=>402, "forall"=>8704,
|
82
|
-
"frac12"=>189, "frac14"=>188, "frac34"=>190, "frasl"=>8260, "gamma"=>947,
|
83
|
-
"ge"=>8805, "gt"=>62, "hArr"=>8660, "harr"=>8596, "hearts"=>9829,
|
84
|
-
"hellip"=>8230, "iacute"=>237, "icirc"=>238, "iexcl"=>161, "igrave"=>236,
|
85
|
-
"image"=>8465, "infin"=>8734, "int"=>8747, "iota"=>953, "iquest"=>191,
|
86
|
-
"isin"=>8712, "iuml"=>239, "kappa"=>954, "lArr"=>8656, "lambda"=>955,
|
87
|
-
"lang"=>9001, "laquo"=>171, "larr"=>8592, "lceil"=>8968, "ldquo"=>8220,
|
88
|
-
"le"=>8804, "lfloor"=>8970, "lowast"=>8727, "loz"=>9674, "lrm"=>8206,
|
89
|
-
"lsaquo"=>8249, "lsquo"=>8216, "lt"=>60, "macr"=>175, "mdash"=>8212,
|
90
|
-
"micro"=>181, "middot"=>183, "minus"=>8722, "mu"=>956, "nabla"=>8711,
|
91
|
-
"nbsp"=>160, "ndash"=>8211, "ne"=>8800, "ni"=>8715, "not"=>172, "notin"=>8713,
|
92
|
-
"nsub"=>8836, "ntilde"=>241, "nu"=>957, "oacute"=>243, "ocirc"=>244,
|
93
|
-
"oelig"=>339, "ograve"=>242, "oline"=>8254, "omega"=>969, "omicron"=>959,
|
94
|
-
"oplus"=>8853, "or"=>8744, "ordf"=>170, "ordm"=>186, "oslash"=>248,
|
95
|
-
"otilde"=>245, "otimes"=>8855, "ouml"=>246, "para"=>182, "part"=>8706,
|
96
|
-
"permil"=>8240, "perp"=>8869, "phi"=>966, "pi"=>960, "piv"=>982,
|
97
|
-
"plusmn"=>177, "pound"=>163, "prime"=>8242, "prod"=>8719, "prop"=>8733,
|
98
|
-
"psi"=>968, "quot"=>34, "rArr"=>8658, "radic"=>8730, "rang"=>9002,
|
99
|
-
"raquo"=>187, "rarr"=>8594, "rceil"=>8969, "rdquo"=>8221, "real"=>8476,
|
100
|
-
"reg"=>174, "rfloor"=>8971, "rho"=>961, "rlm"=>8207, "rsaquo"=>8250,
|
101
|
-
"rsquo"=>8217, "sbquo"=>8218, "scaron"=>353, "sdot"=>8901, "sect"=>167,
|
102
|
-
"shy"=>173, "sigma"=>963, "sigmaf"=>962, "sim"=>8764, "spades"=>9824,
|
103
|
-
"sub"=>8834, "sube"=>8838, "sum"=>8721, "sup"=>8835, "sup1"=>185, "sup2"=>178,
|
104
|
-
"sup3"=>179, "supe"=>8839, "szlig"=>223, "tau"=>964, "there4"=>8756,
|
105
|
-
"theta"=>952, "thetasym"=>977, "thinsp"=>8201, "thorn"=>254, "tilde"=>732,
|
106
|
-
"times"=>215, "trade"=>8482, "uArr"=>8657, "uacute"=>250, "uarr"=>8593,
|
107
|
-
"ucirc"=>251, "ugrave"=>249, "uml"=>168, "upsih"=>978, "upsilon"=>965,
|
108
|
-
"uuml"=>252, "weierp"=>8472, "xi"=>958, "yacute"=>253, "yen"=>165,
|
109
|
-
"yuml"=>255, "zeta"=>950, "zwj"=>8205, "zwnj"=>8204}
|
66
|
+
NamedCharacters = EntityLookup.new
|
110
67
|
end
|
111
68
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module Nokogiri
|
2
2
|
module HTML
|
3
3
|
class Document < XML::Document
|
4
|
+
####
|
5
|
+
# Serialize this Document with +encoding+ using +options+
|
4
6
|
def serialize encoding = nil, options = XML::Node::SaveOptions::FORMAT |
|
5
7
|
XML::Node::SaveOptions::AS_HTML |
|
6
8
|
XML::Node::SaveOptions::NO_DECLARATION |
|
data/lib/nokogiri/version.rb
CHANGED
data/lib/nokogiri/xml.rb
CHANGED
data/lib/nokogiri/xml/builder.rb
CHANGED
@@ -1,14 +1,17 @@
|
|
1
1
|
module Nokogiri
|
2
2
|
module XML
|
3
3
|
class Builder
|
4
|
-
attr_accessor :doc, :parent
|
4
|
+
attr_accessor :doc, :parent, :context
|
5
5
|
def initialize(&block)
|
6
6
|
namespace = self.class.name.split('::')
|
7
7
|
namespace[-1] = 'Document'
|
8
8
|
@doc = eval(namespace.join('::')).new
|
9
9
|
@parent = @doc
|
10
|
-
@context =
|
11
|
-
|
10
|
+
@context = nil
|
11
|
+
if block_given?
|
12
|
+
@context = eval('self', block.binding)
|
13
|
+
end
|
14
|
+
instance_eval(&block) if block_given?
|
12
15
|
@parent = @doc
|
13
16
|
end
|
14
17
|
|
@@ -27,7 +30,7 @@ module Nokogiri
|
|
27
30
|
end
|
28
31
|
|
29
32
|
def method_missing(method, *args, &block)
|
30
|
-
if @context.respond_to?(method)
|
33
|
+
if @context && @context.respond_to?(method)
|
31
34
|
@context.send(method, *args, &block)
|
32
35
|
else
|
33
36
|
node = Nokogiri::XML::Node.new(method.to_s, @doc) { |n|
|
@@ -61,6 +64,7 @@ module Nokogiri
|
|
61
64
|
end
|
62
65
|
|
63
66
|
def method_missing(method, *args, &block)
|
67
|
+
opts = args.last.is_a?(Hash) ? args.pop : {}
|
64
68
|
case method.to_s
|
65
69
|
when /^(.*)!$/
|
66
70
|
@node['id'] = $1
|
@@ -72,9 +76,18 @@ module Nokogiri
|
|
72
76
|
((@node['class'] || '').split(/\s/) + [method.to_s]).join(' ')
|
73
77
|
@node.content = args.first if args.first
|
74
78
|
end
|
79
|
+
|
80
|
+
# Assign any extra options
|
81
|
+
opts.each do |k,v|
|
82
|
+
@node[k.to_s] = ((@node[k.to_s] || '').split(/\s/) + [v]).join(' ')
|
83
|
+
end
|
84
|
+
|
75
85
|
if block_given?
|
86
|
+
old_parent = @doc_builder.parent
|
76
87
|
@doc_builder.parent = @node
|
77
|
-
|
88
|
+
value = @doc_builder.instance_eval(&block)
|
89
|
+
@doc_builder.parent = old_parent
|
90
|
+
return value
|
78
91
|
end
|
79
92
|
self
|
80
93
|
end
|
@@ -1,16 +1,27 @@
|
|
1
1
|
module Nokogiri
|
2
2
|
module XML
|
3
|
+
####
|
4
|
+
# Nokogiri::XML::Document is the main entry point for dealing with
|
5
|
+
# XML documents. The Document is created by parsing an XML document.
|
6
|
+
# See Nokogiri.XML()
|
7
|
+
#
|
8
|
+
# For searching a Document, see Nokogiri::XML::Node#css and
|
9
|
+
# Nokogiri::XML::Node#xpath
|
3
10
|
class Document < Node
|
11
|
+
# A list of Nokogiri::XML::SyntaxError found when parsing a document
|
4
12
|
attr_accessor :errors
|
5
13
|
|
14
|
+
# The name of this document. Always returns "document"
|
6
15
|
def name
|
7
16
|
'document'
|
8
17
|
end
|
9
18
|
|
19
|
+
# A reference to +self+
|
10
20
|
def document
|
11
21
|
self
|
12
22
|
end
|
13
23
|
|
24
|
+
# Get the list of decorators given +key+
|
14
25
|
def decorators(key)
|
15
26
|
@decorators ||= Hash.new
|
16
27
|
@decorators[key] ||= []
|
@@ -37,16 +48,19 @@ module Nokogiri
|
|
37
48
|
}
|
38
49
|
end
|
39
50
|
|
40
|
-
def node_cache
|
51
|
+
def node_cache # :nodoc:
|
41
52
|
@node_cache ||= {}
|
42
53
|
end
|
43
54
|
|
44
55
|
alias :to_xml :serialize
|
45
56
|
alias :inner_html :serialize
|
46
57
|
|
58
|
+
# Get the hash of namespaces on the root Nokogiri::XML::Node
|
47
59
|
def namespaces
|
48
60
|
root ? root.collect_namespaces : {}
|
49
61
|
end
|
62
|
+
|
63
|
+
undef_method :swap, :parent, :namespace
|
50
64
|
end
|
51
65
|
end
|
52
66
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Nokogiri
|
2
|
+
module XML
|
3
|
+
class FragmentHandler < Nokogiri::XML::SAX::Document # :nodoc:
|
4
|
+
def initialize node, original_html
|
5
|
+
@doc_started = false
|
6
|
+
@original_html = original_html
|
7
|
+
@document = node.document
|
8
|
+
@stack = [node]
|
9
|
+
end
|
10
|
+
|
11
|
+
def start_element name, attrs = []
|
12
|
+
@doc_started = true if @original_html =~ /^<#{name}/
|
13
|
+
return unless @doc_started
|
14
|
+
|
15
|
+
node = Node.new(name, @document)
|
16
|
+
Hash[*attrs].each do |k,v|
|
17
|
+
node[k] = v
|
18
|
+
end
|
19
|
+
@stack.last << node
|
20
|
+
@stack << node
|
21
|
+
end
|
22
|
+
|
23
|
+
def characters string
|
24
|
+
@doc_started = true if @original_html =~ /^\s*#{string}/
|
25
|
+
@stack.last << Nokogiri::XML::Text.new(string, @document)
|
26
|
+
end
|
27
|
+
|
28
|
+
def end_element name
|
29
|
+
return unless @stack.last.name == name
|
30
|
+
@stack.pop
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/nokogiri/xml/node.rb
CHANGED
@@ -3,6 +3,36 @@ require 'nokogiri/xml/node/save_options'
|
|
3
3
|
|
4
4
|
module Nokogiri
|
5
5
|
module XML
|
6
|
+
####
|
7
|
+
# Nokogiri::XML::Node is your window to the fun filled world of dealing
|
8
|
+
# with XML and HTML tags. A Nokogiri::XML::Node may be treated similarly
|
9
|
+
# to a hash with regard to attributes. For example (from irb):
|
10
|
+
#
|
11
|
+
# irb(main):004:0> node
|
12
|
+
# => <a href="#foo" id="link">link</a>
|
13
|
+
# irb(main):005:0> node['href']
|
14
|
+
# => "#foo"
|
15
|
+
# irb(main):006:0> node.keys
|
16
|
+
# => ["href", "id"]
|
17
|
+
# irb(main):007:0> node.values
|
18
|
+
# => ["#foo", "link"]
|
19
|
+
# irb(main):008:0> node['class'] = 'green'
|
20
|
+
# => "green"
|
21
|
+
# irb(main):009:0> node
|
22
|
+
# => <a href="#foo" id="link" class="green">link</a>
|
23
|
+
# irb(main):010:0>
|
24
|
+
#
|
25
|
+
# See Nokogiri::XML::Node#[] and Nokogiri::XML#[]= for more information.
|
26
|
+
#
|
27
|
+
# Nokogiri::XML::Node also has methods that let you move around your
|
28
|
+
# tree. For navigating your tree, see:
|
29
|
+
#
|
30
|
+
# * Nokogiri::XML::Node#parent
|
31
|
+
# * Nokogiri::XML::Node#children
|
32
|
+
# * Nokogiri::XML::Node#next
|
33
|
+
# * Nokogiri::XML::Node#previous
|
34
|
+
#
|
35
|
+
# You may search this node's subtree using Node#xpath and Node#css
|
6
36
|
class Node
|
7
37
|
ELEMENT_NODE = 1
|
8
38
|
ATTRIBUTE_NODE = 2
|
@@ -56,10 +86,15 @@ module Nokogiri
|
|
56
86
|
# optional hash of namespaces may be appended.
|
57
87
|
# See Node#xpath and Node#css.
|
58
88
|
def search *paths
|
59
|
-
ns = paths.last.is_a?(Hash) ? paths.pop :
|
89
|
+
ns = paths.last.is_a?(Hash) ? paths.pop :
|
90
|
+
(document.root ? document.root.namespaces : {})
|
60
91
|
xpath(*(paths.map { |path|
|
61
92
|
path = path.to_s
|
62
|
-
path =~ /^(\.\/|\/)/ ? path : CSS.xpath_for(
|
93
|
+
path =~ /^(\.\/|\/)/ ? path : CSS.xpath_for(
|
94
|
+
path,
|
95
|
+
:prefix => ".//",
|
96
|
+
:ns => ns
|
97
|
+
)
|
63
98
|
}.flatten.uniq) + [ns])
|
64
99
|
end
|
65
100
|
alias :/ :search
|
@@ -88,9 +123,10 @@ module Nokogiri
|
|
88
123
|
Hash, String, Symbol
|
89
124
|
].include?(paths.last.class) ? paths.pop : nil
|
90
125
|
|
91
|
-
ns = paths.last.is_a?(Hash) ? paths.pop :
|
126
|
+
ns = paths.last.is_a?(Hash) ? paths.pop :
|
127
|
+
(document.root ? document.root.namespaces : {})
|
92
128
|
|
93
|
-
return NodeSet.new(document) unless document
|
129
|
+
return NodeSet.new(document) unless document
|
94
130
|
|
95
131
|
sets = paths.map { |path|
|
96
132
|
ctx = XPathContext.new(self)
|
@@ -138,7 +174,8 @@ module Nokogiri
|
|
138
174
|
Hash, String, Symbol
|
139
175
|
].include?(rules.last.class) ? rules.pop : nil
|
140
176
|
|
141
|
-
ns = rules.last.is_a?(Hash) ? rules.pop :
|
177
|
+
ns = rules.last.is_a?(Hash) ? rules.pop :
|
178
|
+
(document.root ? document.root.namespaces : {})
|
142
179
|
|
143
180
|
rules = rules.map { |rule|
|
144
181
|
CSS.xpath_for(rule, :prefix => ".//", :ns => ns)
|
@@ -150,15 +187,15 @@ module Nokogiri
|
|
150
187
|
###
|
151
188
|
# Search for the first occurrence of +path+.
|
152
189
|
# Returns nil if nothing is found, otherwise a Node.
|
153
|
-
def at path, ns = document.root.namespaces
|
190
|
+
def at path, ns = document.root ? document.root.namespaces : {}
|
154
191
|
search(path, ns).first
|
155
192
|
end
|
156
193
|
|
157
194
|
###
|
158
195
|
# Get the attribute value for the attribute +name+
|
159
|
-
def []
|
160
|
-
return nil unless key?(name)
|
161
|
-
get(name)
|
196
|
+
def [] name
|
197
|
+
return nil unless key?(name.to_s)
|
198
|
+
get(name.to_s)
|
162
199
|
end
|
163
200
|
|
164
201
|
alias :next :next_sibling
|
@@ -215,32 +252,59 @@ module Nokogiri
|
|
215
252
|
# Create nodes from +data+ and insert them before this node
|
216
253
|
# (as a sibling).
|
217
254
|
def before data
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
parser.parse(data)
|
255
|
+
fragment(data).children.each do |node|
|
256
|
+
add_previous_sibling node
|
257
|
+
end
|
258
|
+
self
|
223
259
|
end
|
224
260
|
|
225
261
|
####
|
226
262
|
# Create nodes from +data+ and insert them after this node
|
227
263
|
# (as a sibling).
|
228
264
|
def after data
|
265
|
+
fragment(data).children.to_a.reverse.each do |node|
|
266
|
+
add_next_sibling node
|
267
|
+
end
|
268
|
+
self
|
269
|
+
end
|
270
|
+
|
271
|
+
####
|
272
|
+
# Swap this Node for new nodes made from +data+
|
273
|
+
def swap data
|
274
|
+
before(data)
|
275
|
+
remove
|
276
|
+
self
|
277
|
+
end
|
278
|
+
|
279
|
+
####
|
280
|
+
# Set the inner_html for this Node to +tags+
|
281
|
+
def inner_html= tags
|
282
|
+
children.each { |x| x.remove}
|
283
|
+
|
284
|
+
fragment(tags).children.to_a.reverse.each do |node|
|
285
|
+
add_child node
|
286
|
+
end
|
287
|
+
self
|
288
|
+
end
|
289
|
+
|
290
|
+
####
|
291
|
+
# Create a Nokogiri::XML::DocumentFragment from +tags+
|
292
|
+
def fragment tags
|
229
293
|
classes = document.class.name.split('::')
|
230
294
|
classes[-1] = 'SAX::Parser'
|
231
295
|
|
232
|
-
|
233
|
-
|
234
|
-
parser.
|
235
|
-
|
236
|
-
|
237
|
-
|
296
|
+
|
297
|
+
fragment = DocumentFragment.new(self.document)
|
298
|
+
parser = eval(classes.join('::')).new(
|
299
|
+
FragmentHandler.new(fragment, tags)
|
300
|
+
)
|
301
|
+
parser.parse(tags)
|
302
|
+
fragment
|
238
303
|
end
|
239
304
|
|
240
305
|
####
|
241
306
|
# Set the content to +string+.
|
242
|
-
|
243
|
-
def content= string, encode = true
|
307
|
+
def content= string
|
244
308
|
self.native_content = encode_special_chars(string)
|
245
309
|
end
|
246
310
|
|
@@ -251,22 +315,27 @@ module Nokogiri
|
|
251
315
|
parent_node
|
252
316
|
end
|
253
317
|
|
318
|
+
# Returns true if this is a Comment
|
254
319
|
def comment?
|
255
320
|
type == COMMENT_NODE
|
256
321
|
end
|
257
322
|
|
323
|
+
# Returns true if this is a CDATA
|
258
324
|
def cdata?
|
259
325
|
type == CDATA_SECTION_NODE
|
260
326
|
end
|
261
327
|
|
328
|
+
# Returns true if this is an XML::Document node
|
262
329
|
def xml?
|
263
330
|
type == DOCUMENT_NODE
|
264
331
|
end
|
265
332
|
|
333
|
+
# Returns true if this is an HTML::Document node
|
266
334
|
def html?
|
267
335
|
type == HTML_DOCUMENT_NODE
|
268
336
|
end
|
269
337
|
|
338
|
+
# Returns true if this is a Text node
|
270
339
|
def text?
|
271
340
|
type == TEXT_NODE
|
272
341
|
end
|
@@ -276,6 +345,7 @@ module Nokogiri
|
|
276
345
|
[NOTATION_NODE, ENTITY_NODE, ENTITY_DECL].include?(type)
|
277
346
|
end
|
278
347
|
|
348
|
+
# Returns true if this is an Element node
|
279
349
|
def element?
|
280
350
|
type == ELEMENT_NODE
|
281
351
|
end
|
@@ -289,6 +359,7 @@ module Nokogiri
|
|
289
359
|
children.map { |x| x.to_html }.join
|
290
360
|
end
|
291
361
|
|
362
|
+
# Get the path to this node as a CSS expression
|
292
363
|
def css_path
|
293
364
|
path.split(/\//).map { |part|
|
294
365
|
part.length == 0 ? nil : part.gsub(/\[(\d+)\]/, ':nth-of-type(\1)')
|
@@ -306,13 +377,12 @@ module Nokogiri
|
|
306
377
|
###
|
307
378
|
# Get a list of ancestor Node for this Node
|
308
379
|
def ancestors
|
309
|
-
|
380
|
+
return [] unless respond_to?(:parent)
|
310
381
|
|
311
|
-
|
382
|
+
parents = [parent]
|
312
383
|
|
313
|
-
while
|
314
|
-
parents <<
|
315
|
-
this_parent = this_parent.parent
|
384
|
+
while parents.last.respond_to?(:parent)
|
385
|
+
parents << parents.last.parent
|
316
386
|
end
|
317
387
|
parents
|
318
388
|
end
|
@@ -327,7 +397,7 @@ module Nokogiri
|
|
327
397
|
####
|
328
398
|
# replace node with the new node in the document.
|
329
399
|
def replace(new_node)
|
330
|
-
if new_node.is_a?(Document)
|
400
|
+
if new_node.is_a?(Document) || !new_node.is_a?(XML::Node)
|
331
401
|
raise ArgumentError, <<-EOERR
|
332
402
|
Node.replace requires a Node argument, and cannot accept a Document.
|
333
403
|
(You probably want to select a node from the Document with at() or search(), or create a new Node via Node.new().)
|
@@ -428,8 +498,13 @@ Node.replace requires a Node argument, and cannot accept a Document.
|
|
428
498
|
write_to io, encoding, SaveOptions::FORMAT | SaveOptions::AS_XML
|
429
499
|
end
|
430
500
|
|
501
|
+
# Create a new node from +string+
|
502
|
+
#
|
503
|
+
# THIS METHOD IS DEPRECATED
|
504
|
+
# This method is deprecated and will be removed in 1.3.0 or by
|
505
|
+
# March 1, 2009. Instead, use Nokogiri::XML::Node#fragment()
|
431
506
|
def self.new_from_str string
|
432
|
-
$stderr.puts("This method is deprecated and will be removed in 1.
|
507
|
+
$stderr.puts("This method is deprecated and will be removed in 1.3.0 or by March 1, 2009. Instead, use Nokogiri::XML::Node#fragment")
|
433
508
|
Nokogiri::HTML.fragment(string).first
|
434
509
|
end
|
435
510
|
end
|