nokogiri 1.3.0-x86-mswin32
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 +27 -0
- data/CHANGELOG.ja.rdoc +233 -0
- data/CHANGELOG.rdoc +222 -0
- data/Manifest.txt +247 -0
- data/README.ja.rdoc +103 -0
- data/README.rdoc +117 -0
- data/Rakefile +205 -0
- data/bin/nokogiri +47 -0
- data/ext/nokogiri/extconf.rb +89 -0
- data/ext/nokogiri/html_document.c +183 -0
- data/ext/nokogiri/html_document.h +10 -0
- data/ext/nokogiri/html_element_description.c +272 -0
- data/ext/nokogiri/html_element_description.h +10 -0
- data/ext/nokogiri/html_entity_lookup.c +30 -0
- data/ext/nokogiri/html_entity_lookup.h +8 -0
- data/ext/nokogiri/html_sax_parser.c +57 -0
- data/ext/nokogiri/html_sax_parser.h +11 -0
- data/ext/nokogiri/iconv.dll +0 -0
- data/ext/nokogiri/libexslt.dll +0 -0
- data/ext/nokogiri/libxml2.dll +0 -0
- data/ext/nokogiri/libxslt.dll +0 -0
- data/ext/nokogiri/nokogiri.c +81 -0
- data/ext/nokogiri/nokogiri.h +149 -0
- data/ext/nokogiri/xml_attr.c +92 -0
- data/ext/nokogiri/xml_attr.h +9 -0
- data/ext/nokogiri/xml_cdata.c +53 -0
- data/ext/nokogiri/xml_cdata.h +9 -0
- data/ext/nokogiri/xml_comment.c +51 -0
- data/ext/nokogiri/xml_comment.h +9 -0
- data/ext/nokogiri/xml_document.c +308 -0
- data/ext/nokogiri/xml_document.h +21 -0
- data/ext/nokogiri/xml_document_fragment.c +48 -0
- data/ext/nokogiri/xml_document_fragment.h +10 -0
- data/ext/nokogiri/xml_dtd.c +102 -0
- data/ext/nokogiri/xml_dtd.h +8 -0
- data/ext/nokogiri/xml_entity_reference.c +50 -0
- data/ext/nokogiri/xml_entity_reference.h +9 -0
- data/ext/nokogiri/xml_io.c +24 -0
- data/ext/nokogiri/xml_io.h +10 -0
- data/ext/nokogiri/xml_namespace.c +69 -0
- data/ext/nokogiri/xml_namespace.h +12 -0
- data/ext/nokogiri/xml_node.c +928 -0
- data/ext/nokogiri/xml_node.h +14 -0
- data/ext/nokogiri/xml_node_set.c +386 -0
- data/ext/nokogiri/xml_node_set.h +9 -0
- data/ext/nokogiri/xml_processing_instruction.c +54 -0
- data/ext/nokogiri/xml_processing_instruction.h +9 -0
- data/ext/nokogiri/xml_reader.c +572 -0
- data/ext/nokogiri/xml_reader.h +10 -0
- data/ext/nokogiri/xml_relax_ng.c +106 -0
- data/ext/nokogiri/xml_relax_ng.h +9 -0
- data/ext/nokogiri/xml_sax_parser.c +336 -0
- data/ext/nokogiri/xml_sax_parser.h +10 -0
- data/ext/nokogiri/xml_sax_push_parser.c +86 -0
- data/ext/nokogiri/xml_sax_push_parser.h +9 -0
- data/ext/nokogiri/xml_schema.c +107 -0
- data/ext/nokogiri/xml_schema.h +9 -0
- data/ext/nokogiri/xml_syntax_error.c +203 -0
- data/ext/nokogiri/xml_syntax_error.h +12 -0
- data/ext/nokogiri/xml_text.c +47 -0
- data/ext/nokogiri/xml_text.h +9 -0
- data/ext/nokogiri/xml_xpath.c +53 -0
- data/ext/nokogiri/xml_xpath.h +11 -0
- data/ext/nokogiri/xml_xpath_context.c +252 -0
- data/ext/nokogiri/xml_xpath_context.h +9 -0
- data/ext/nokogiri/xslt_stylesheet.c +131 -0
- data/ext/nokogiri/xslt_stylesheet.h +9 -0
- data/ext/nokogiri/zlib1.dll +0 -0
- data/lib/action-nokogiri.rb +36 -0
- data/lib/nokogiri.rb +110 -0
- data/lib/nokogiri/1.8/nokogiri.so +0 -0
- data/lib/nokogiri/1.9/nokogiri.so +0 -0
- data/lib/nokogiri/css.rb +25 -0
- data/lib/nokogiri/css/generated_parser.rb +748 -0
- data/lib/nokogiri/css/generated_tokenizer.rb +144 -0
- data/lib/nokogiri/css/node.rb +107 -0
- data/lib/nokogiri/css/parser.rb +82 -0
- data/lib/nokogiri/css/parser.y +227 -0
- data/lib/nokogiri/css/syntax_error.rb +7 -0
- data/lib/nokogiri/css/tokenizer.rb +11 -0
- data/lib/nokogiri/css/tokenizer.rex +54 -0
- data/lib/nokogiri/css/xpath_visitor.rb +172 -0
- data/lib/nokogiri/decorators.rb +2 -0
- data/lib/nokogiri/decorators/hpricot.rb +3 -0
- data/lib/nokogiri/decorators/hpricot/node.rb +56 -0
- data/lib/nokogiri/decorators/hpricot/node_set.rb +54 -0
- data/lib/nokogiri/decorators/hpricot/xpath_visitor.rb +30 -0
- data/lib/nokogiri/decorators/slop.rb +33 -0
- data/lib/nokogiri/ffi/html/document.rb +37 -0
- data/lib/nokogiri/ffi/html/element_description.rb +85 -0
- data/lib/nokogiri/ffi/html/entity_lookup.rb +16 -0
- data/lib/nokogiri/ffi/html/sax/parser.rb +21 -0
- data/lib/nokogiri/ffi/io_callbacks.rb +32 -0
- data/lib/nokogiri/ffi/libxml.rb +314 -0
- data/lib/nokogiri/ffi/structs/common_node.rb +26 -0
- data/lib/nokogiri/ffi/structs/html_elem_desc.rb +24 -0
- data/lib/nokogiri/ffi/structs/html_entity_desc.rb +13 -0
- data/lib/nokogiri/ffi/structs/xml_alloc.rb +16 -0
- data/lib/nokogiri/ffi/structs/xml_attr.rb +19 -0
- data/lib/nokogiri/ffi/structs/xml_buffer.rb +16 -0
- data/lib/nokogiri/ffi/structs/xml_document.rb +108 -0
- data/lib/nokogiri/ffi/structs/xml_dtd.rb +26 -0
- data/lib/nokogiri/ffi/structs/xml_node.rb +28 -0
- data/lib/nokogiri/ffi/structs/xml_node_set.rb +53 -0
- data/lib/nokogiri/ffi/structs/xml_notation.rb +11 -0
- data/lib/nokogiri/ffi/structs/xml_ns.rb +15 -0
- data/lib/nokogiri/ffi/structs/xml_relax_ng.rb +14 -0
- data/lib/nokogiri/ffi/structs/xml_sax_handler.rb +51 -0
- data/lib/nokogiri/ffi/structs/xml_sax_push_parser_context.rb +14 -0
- data/lib/nokogiri/ffi/structs/xml_schema.rb +13 -0
- data/lib/nokogiri/ffi/structs/xml_syntax_error.rb +31 -0
- data/lib/nokogiri/ffi/structs/xml_text_reader.rb +12 -0
- data/lib/nokogiri/ffi/structs/xml_xpath_context.rb +37 -0
- data/lib/nokogiri/ffi/structs/xml_xpath_object.rb +35 -0
- data/lib/nokogiri/ffi/structs/xml_xpath_parser_context.rb +20 -0
- data/lib/nokogiri/ffi/structs/xslt_stylesheet.rb +13 -0
- data/lib/nokogiri/ffi/xml/attr.rb +41 -0
- data/lib/nokogiri/ffi/xml/cdata.rb +19 -0
- data/lib/nokogiri/ffi/xml/comment.rb +18 -0
- data/lib/nokogiri/ffi/xml/document.rb +107 -0
- data/lib/nokogiri/ffi/xml/document_fragment.rb +26 -0
- data/lib/nokogiri/ffi/xml/dtd.rb +42 -0
- data/lib/nokogiri/ffi/xml/entity_reference.rb +19 -0
- data/lib/nokogiri/ffi/xml/namespace.rb +38 -0
- data/lib/nokogiri/ffi/xml/node.rb +380 -0
- data/lib/nokogiri/ffi/xml/node_set.rb +130 -0
- data/lib/nokogiri/ffi/xml/processing_instruction.rb +20 -0
- data/lib/nokogiri/ffi/xml/reader.rb +217 -0
- data/lib/nokogiri/ffi/xml/relax_ng.rb +51 -0
- data/lib/nokogiri/ffi/xml/sax/parser.rb +148 -0
- data/lib/nokogiri/ffi/xml/sax/push_parser.rb +38 -0
- data/lib/nokogiri/ffi/xml/schema.rb +55 -0
- data/lib/nokogiri/ffi/xml/syntax_error.rb +76 -0
- data/lib/nokogiri/ffi/xml/text.rb +18 -0
- data/lib/nokogiri/ffi/xml/xpath.rb +19 -0
- data/lib/nokogiri/ffi/xml/xpath_context.rb +135 -0
- data/lib/nokogiri/ffi/xslt/stylesheet.rb +47 -0
- data/lib/nokogiri/hpricot.rb +62 -0
- data/lib/nokogiri/html.rb +34 -0
- data/lib/nokogiri/html/builder.rb +35 -0
- data/lib/nokogiri/html/document.rb +71 -0
- data/lib/nokogiri/html/document_fragment.rb +15 -0
- data/lib/nokogiri/html/element_description.rb +23 -0
- data/lib/nokogiri/html/entity_lookup.rb +13 -0
- data/lib/nokogiri/html/sax/parser.rb +47 -0
- data/lib/nokogiri/nokogiri.rb +1 -0
- data/lib/nokogiri/syntax_error.rb +4 -0
- data/lib/nokogiri/version.rb +29 -0
- data/lib/nokogiri/version_warning.rb +11 -0
- data/lib/nokogiri/xml.rb +62 -0
- data/lib/nokogiri/xml/attr.rb +9 -0
- data/lib/nokogiri/xml/builder.rb +254 -0
- data/lib/nokogiri/xml/cdata.rb +11 -0
- data/lib/nokogiri/xml/document.rb +100 -0
- data/lib/nokogiri/xml/document_fragment.rb +49 -0
- data/lib/nokogiri/xml/dtd.rb +11 -0
- data/lib/nokogiri/xml/entity_declaration.rb +11 -0
- data/lib/nokogiri/xml/fragment_handler.rb +55 -0
- data/lib/nokogiri/xml/namespace.rb +7 -0
- data/lib/nokogiri/xml/node.rb +745 -0
- data/lib/nokogiri/xml/node/save_options.rb +42 -0
- data/lib/nokogiri/xml/node_set.rb +238 -0
- data/lib/nokogiri/xml/notation.rb +6 -0
- data/lib/nokogiri/xml/parse_options.rb +80 -0
- data/lib/nokogiri/xml/processing_instruction.rb +8 -0
- data/lib/nokogiri/xml/reader.rb +66 -0
- data/lib/nokogiri/xml/relax_ng.rb +32 -0
- data/lib/nokogiri/xml/sax.rb +3 -0
- data/lib/nokogiri/xml/sax/document.rb +143 -0
- data/lib/nokogiri/xml/sax/parser.rb +101 -0
- data/lib/nokogiri/xml/sax/push_parser.rb +60 -0
- data/lib/nokogiri/xml/schema.rb +65 -0
- data/lib/nokogiri/xml/syntax_error.rb +34 -0
- data/lib/nokogiri/xml/xpath.rb +10 -0
- data/lib/nokogiri/xml/xpath/syntax_error.rb +8 -0
- data/lib/nokogiri/xml/xpath_context.rb +16 -0
- data/lib/nokogiri/xslt.rb +48 -0
- data/lib/nokogiri/xslt/stylesheet.rb +25 -0
- data/lib/xsd/xmlparser/nokogiri.rb +64 -0
- data/tasks/test.rb +161 -0
- data/test/css/test_nthiness.rb +160 -0
- data/test/css/test_parser.rb +277 -0
- data/test/css/test_tokenizer.rb +176 -0
- data/test/css/test_xpath_visitor.rb +76 -0
- data/test/ffi/test_document.rb +35 -0
- data/test/files/address_book.rlx +12 -0
- data/test/files/address_book.xml +10 -0
- data/test/files/dont_hurt_em_why.xml +422 -0
- data/test/files/exslt.xml +8 -0
- data/test/files/exslt.xslt +35 -0
- data/test/files/po.xml +32 -0
- data/test/files/po.xsd +66 -0
- data/test/files/staff.xml +59 -0
- data/test/files/staff.xslt +32 -0
- data/test/files/tlm.html +850 -0
- data/test/helper.rb +123 -0
- data/test/hpricot/files/basic.xhtml +17 -0
- data/test/hpricot/files/boingboing.html +2266 -0
- data/test/hpricot/files/cy0.html +3653 -0
- data/test/hpricot/files/immob.html +400 -0
- data/test/hpricot/files/pace_application.html +1320 -0
- data/test/hpricot/files/tenderlove.html +16 -0
- data/test/hpricot/files/uswebgen.html +220 -0
- data/test/hpricot/files/utf8.html +1054 -0
- data/test/hpricot/files/week9.html +1723 -0
- data/test/hpricot/files/why.xml +19 -0
- data/test/hpricot/load_files.rb +11 -0
- data/test/hpricot/test_alter.rb +68 -0
- data/test/hpricot/test_builder.rb +20 -0
- data/test/hpricot/test_parser.rb +426 -0
- data/test/hpricot/test_paths.rb +15 -0
- data/test/hpricot/test_preserved.rb +77 -0
- data/test/hpricot/test_xml.rb +30 -0
- data/test/html/sax/test_parser.rb +52 -0
- data/test/html/test_builder.rb +156 -0
- data/test/html/test_document.rb +361 -0
- data/test/html/test_document_encoding.rb +46 -0
- data/test/html/test_document_fragment.rb +97 -0
- data/test/html/test_element_description.rb +95 -0
- data/test/html/test_named_characters.rb +14 -0
- data/test/html/test_node.rb +165 -0
- data/test/test_convert_xpath.rb +186 -0
- data/test/test_css_cache.rb +56 -0
- data/test/test_gc.rb +15 -0
- data/test/test_memory_leak.rb +77 -0
- data/test/test_nokogiri.rb +127 -0
- data/test/test_reader.rb +316 -0
- data/test/test_xslt_transforms.rb +131 -0
- data/test/xml/node/test_save_options.rb +20 -0
- data/test/xml/node/test_subclass.rb +44 -0
- data/test/xml/sax/test_parser.rb +169 -0
- data/test/xml/sax/test_push_parser.rb +92 -0
- data/test/xml/test_attr.rb +38 -0
- data/test/xml/test_builder.rb +73 -0
- data/test/xml/test_cdata.rb +38 -0
- data/test/xml/test_comment.rb +23 -0
- data/test/xml/test_document.rb +397 -0
- data/test/xml/test_document_encoding.rb +26 -0
- data/test/xml/test_document_fragment.rb +76 -0
- data/test/xml/test_dtd.rb +42 -0
- data/test/xml/test_dtd_encoding.rb +31 -0
- data/test/xml/test_entity_reference.rb +21 -0
- data/test/xml/test_namespace.rb +43 -0
- data/test/xml/test_node.rb +808 -0
- data/test/xml/test_node_attributes.rb +34 -0
- data/test/xml/test_node_encoding.rb +84 -0
- data/test/xml/test_node_set.rb +368 -0
- data/test/xml/test_parse_options.rb +52 -0
- data/test/xml/test_processing_instruction.rb +30 -0
- data/test/xml/test_reader_encoding.rb +126 -0
- data/test/xml/test_relax_ng.rb +60 -0
- data/test/xml/test_schema.rb +65 -0
- data/test/xml/test_text.rb +18 -0
- data/test/xml/test_unparented_node.rb +381 -0
- data/test/xml/test_xpath.rb +106 -0
- metadata +409 -0
@@ -0,0 +1,100 @@
|
|
1
|
+
module Nokogiri
|
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
|
10
|
+
class Document < Node
|
11
|
+
# A list of Nokogiri::XML::SyntaxError found when parsing a document
|
12
|
+
attr_accessor :errors
|
13
|
+
|
14
|
+
def initialize *args
|
15
|
+
@decorators = nil
|
16
|
+
end
|
17
|
+
|
18
|
+
# The name of this document. Always returns "document"
|
19
|
+
def name
|
20
|
+
'document'
|
21
|
+
end
|
22
|
+
|
23
|
+
# A reference to +self+
|
24
|
+
def document
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
# Get the list of decorators given +key+
|
29
|
+
def decorators key
|
30
|
+
@decorators ||= Hash.new
|
31
|
+
@decorators[key] ||= []
|
32
|
+
end
|
33
|
+
|
34
|
+
###
|
35
|
+
# Explore a document with shortcut methods.
|
36
|
+
def slop!
|
37
|
+
unless decorators(XML::Node).include? Nokogiri::Decorators::Slop
|
38
|
+
decorators(XML::Node) << Nokogiri::Decorators::Slop
|
39
|
+
decorate!
|
40
|
+
end
|
41
|
+
|
42
|
+
self
|
43
|
+
end
|
44
|
+
|
45
|
+
###
|
46
|
+
# Apply any decorators to +node+
|
47
|
+
def decorate node
|
48
|
+
return unless @decorators
|
49
|
+
@decorators.each { |klass,list|
|
50
|
+
next unless node.is_a?(klass)
|
51
|
+
list.each { |moodule| node.extend(moodule) }
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
alias :to_xml :serialize
|
56
|
+
alias :inner_html :serialize
|
57
|
+
|
58
|
+
# Get the hash of namespaces on the root Nokogiri::XML::Node
|
59
|
+
def namespaces
|
60
|
+
root ? root.collect_namespaces : {}
|
61
|
+
end
|
62
|
+
|
63
|
+
####
|
64
|
+
# Create a Nokogiri::XML::DocumentFragment from +tags+
|
65
|
+
def fragment tags
|
66
|
+
DocumentFragment.new(self, tags)
|
67
|
+
end
|
68
|
+
|
69
|
+
undef_method :swap, :parent, :namespace
|
70
|
+
|
71
|
+
class << self
|
72
|
+
###
|
73
|
+
# Parse an XML file. +thing+ may be a String, or any object that
|
74
|
+
# responds to _read_ and _close_ such as an IO, or StringIO.
|
75
|
+
# +url+ is resource where this document is located. +encoding+ is the
|
76
|
+
# encoding that should be used when processing the document. +options+
|
77
|
+
# is a number that sets options in the parser, such as
|
78
|
+
# Nokogiri::XML::PARSE_RECOVER. See the constants in
|
79
|
+
# Nokogiri::XML.
|
80
|
+
def parse string_or_io, url = nil, encoding = nil, options = 2145, &block
|
81
|
+
|
82
|
+
options = Nokogiri::XML::ParseOptions.new(options) if Fixnum === options
|
83
|
+
# Give the options to the user
|
84
|
+
yield options if block_given?
|
85
|
+
|
86
|
+
if string_or_io.respond_to?(:read)
|
87
|
+
url ||= string_or_io.respond_to?(:path) ? string_or_io.path : nil
|
88
|
+
return self.read_io(string_or_io, url, encoding, options.to_i)
|
89
|
+
end
|
90
|
+
|
91
|
+
# read_memory pukes on empty docs
|
92
|
+
return self.new if string_or_io.nil? or string_or_io.empty?
|
93
|
+
|
94
|
+
self.read_memory(string_or_io, url, encoding, options.to_i)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Nokogiri
|
2
|
+
module XML
|
3
|
+
class DocumentFragment < Nokogiri::XML::Node
|
4
|
+
def initialize document, tags=nil
|
5
|
+
if tags
|
6
|
+
parser = if self.kind_of?(Nokogiri::HTML::DocumentFragment)
|
7
|
+
HTML::SAX::Parser.new(FragmentHandler.new(self, tags))
|
8
|
+
else
|
9
|
+
XML::SAX::Parser.new(FragmentHandler.new(self, tags))
|
10
|
+
end
|
11
|
+
parser.parse(tags)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
###
|
16
|
+
# return the name for DocumentFragment
|
17
|
+
def name
|
18
|
+
'#document-fragment'
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
children.to_s
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_html *args
|
26
|
+
children.to_html(*args)
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_xhtml *args
|
30
|
+
children.to_xhtml(*args)
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_xml *args
|
34
|
+
children.to_xml(*args)
|
35
|
+
end
|
36
|
+
|
37
|
+
alias :serialize :to_s
|
38
|
+
|
39
|
+
class << self
|
40
|
+
####
|
41
|
+
# Create a Nokogiri::XML::DocumentFragment from +tags+
|
42
|
+
def parse tags
|
43
|
+
XML::DocumentFragment.new(XML::Document.new, tags)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,55 @@
|
|
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
|
+
@document = node.document
|
7
|
+
@stack = [node]
|
8
|
+
@klass = if node.kind_of?(Nokogiri::HTML::DocumentFragment)
|
9
|
+
Nokogiri::HTML::DocumentFragment
|
10
|
+
else
|
11
|
+
Nokogiri::XML::DocumentFragment
|
12
|
+
end
|
13
|
+
#
|
14
|
+
# the regexes used in start_element() and characters() anchor at
|
15
|
+
# start-of-line, but we really only want them to anchor at
|
16
|
+
# start-of-doc. so let's only save up to the first newline.
|
17
|
+
#
|
18
|
+
# this implementation choice was the result of some benchmarks, if
|
19
|
+
# you're curious: http://gist.github.com/115936
|
20
|
+
#
|
21
|
+
newline_index = original_html.index("\n")
|
22
|
+
@original_html = if newline_index
|
23
|
+
original_html[0,newline_index]
|
24
|
+
else
|
25
|
+
original_html
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def start_element name, attrs = []
|
30
|
+
regex = (@klass == Nokogiri::HTML::DocumentFragment) ? %r{^\s*<#{Regexp.escape(name)}}i \
|
31
|
+
: %r{^\s*<#{Regexp.escape(name)}}
|
32
|
+
@doc_started = true if @original_html =~ regex
|
33
|
+
return unless @doc_started
|
34
|
+
|
35
|
+
node = Node.new(name, @document)
|
36
|
+
attrs << "" unless (attrs.length % 2) == 0
|
37
|
+
Hash[*attrs].each do |k,v|
|
38
|
+
node[k] = v
|
39
|
+
end
|
40
|
+
@stack.last << node
|
41
|
+
@stack << node
|
42
|
+
end
|
43
|
+
|
44
|
+
def characters string
|
45
|
+
@doc_started = true if @original_html.strip =~ %r{^\s*#{Regexp.escape(string.strip)}}
|
46
|
+
@stack.last << Nokogiri::XML::Text.new(string, @document)
|
47
|
+
end
|
48
|
+
|
49
|
+
def end_element name
|
50
|
+
return unless @stack.last.name == name
|
51
|
+
@stack.pop
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,745 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
require 'nokogiri/xml/node/save_options'
|
3
|
+
|
4
|
+
module Nokogiri
|
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
|
36
|
+
class Node
|
37
|
+
# Element node type, see Nokogiri::XML::Node#element?
|
38
|
+
ELEMENT_NODE = 1
|
39
|
+
# Attribute node type
|
40
|
+
ATTRIBUTE_NODE = 2
|
41
|
+
# Text node type, see Nokogiri::XML::Node#text?
|
42
|
+
TEXT_NODE = 3
|
43
|
+
# CDATA node type, see Nokogiri::XML::Node#cdata?
|
44
|
+
CDATA_SECTION_NODE = 4
|
45
|
+
# Entity reference node type
|
46
|
+
ENTITY_REF_NODE = 5
|
47
|
+
# Entity node type
|
48
|
+
ENTITY_NODE = 6
|
49
|
+
# PI node type
|
50
|
+
PI_NODE = 7
|
51
|
+
# Comment node type, see Nokogiri::XML::Node#comment?
|
52
|
+
COMMENT_NODE = 8
|
53
|
+
# Document node type, see Nokogiri::XML::Node#xml?
|
54
|
+
DOCUMENT_NODE = 9
|
55
|
+
# Document type node type
|
56
|
+
DOCUMENT_TYPE_NODE = 10
|
57
|
+
# Document fragment node type
|
58
|
+
DOCUMENT_FRAG_NODE = 11
|
59
|
+
# Notation node type
|
60
|
+
NOTATION_NODE = 12
|
61
|
+
# HTML document node type, see Nokogiri::XML::Node#html?
|
62
|
+
HTML_DOCUMENT_NODE = 13
|
63
|
+
# DTD node type
|
64
|
+
DTD_NODE = 14
|
65
|
+
# Element declaration type
|
66
|
+
ELEMENT_DECL = 15
|
67
|
+
# Attribute declaration type
|
68
|
+
ATTRIBUTE_DECL = 16
|
69
|
+
# Entity declaration type
|
70
|
+
ENTITY_DECL = 17
|
71
|
+
# Namespace declaration type
|
72
|
+
NAMESPACE_DECL = 18
|
73
|
+
# XInclude start type
|
74
|
+
XINCLUDE_START = 19
|
75
|
+
# XInclude end type
|
76
|
+
XINCLUDE_END = 20
|
77
|
+
# DOCB document node type
|
78
|
+
DOCB_DOCUMENT_NODE = 21
|
79
|
+
|
80
|
+
def initialize name, document
|
81
|
+
# ... Ya. This is empty on purpose.
|
82
|
+
end
|
83
|
+
|
84
|
+
###
|
85
|
+
# Decorate this node with the decorators set up in this node's Document
|
86
|
+
def decorate!
|
87
|
+
document.decorate(self)
|
88
|
+
end
|
89
|
+
|
90
|
+
###
|
91
|
+
# Search this node for +paths+. +paths+ can be XPath or CSS, and an
|
92
|
+
# optional hash of namespaces may be appended.
|
93
|
+
# See Node#xpath and Node#css.
|
94
|
+
def search *paths
|
95
|
+
ns = paths.last.is_a?(Hash) ? paths.pop :
|
96
|
+
(document.root ? document.root.namespaces : {})
|
97
|
+
xpath(*(paths.map { |path|
|
98
|
+
path = path.to_s
|
99
|
+
path =~ /^(\.\/|\/)/ ? path : CSS.xpath_for(
|
100
|
+
path,
|
101
|
+
:prefix => ".//",
|
102
|
+
:ns => ns
|
103
|
+
)
|
104
|
+
}.flatten.uniq) + [ns])
|
105
|
+
end
|
106
|
+
alias :/ :search
|
107
|
+
|
108
|
+
###
|
109
|
+
# Search this node for XPath +paths+. +paths+ must be one or more XPath
|
110
|
+
# queries. A hash of namespaces may be appended. For example:
|
111
|
+
#
|
112
|
+
# node.xpath('.//title')
|
113
|
+
# node.xpath('.//foo:name', { 'foo' => 'http://example.org/' })
|
114
|
+
# node.xpath('.//xmlns:name', node.root.namespaces)
|
115
|
+
#
|
116
|
+
# Custom XPath functions may also be defined. To define custom functions
|
117
|
+
# create a class and implement the # function you want to define.
|
118
|
+
# For example:
|
119
|
+
#
|
120
|
+
# node.xpath('.//title[regex(., "\w+")]', Class.new {
|
121
|
+
# def regex node_set, regex
|
122
|
+
# node_set.find_all { |node| node['some_attribute'] =~ /#{regex}/ }
|
123
|
+
# end
|
124
|
+
# }.new)
|
125
|
+
#
|
126
|
+
def xpath *paths
|
127
|
+
# Pop off our custom function handler if it exists
|
128
|
+
handler = ![
|
129
|
+
Hash, String, Symbol
|
130
|
+
].include?(paths.last.class) ? paths.pop : nil
|
131
|
+
|
132
|
+
ns = paths.last.is_a?(Hash) ? paths.pop :
|
133
|
+
(document.root ? document.root.namespaces : {})
|
134
|
+
|
135
|
+
return NodeSet.new(document) unless document
|
136
|
+
|
137
|
+
sets = paths.map { |path|
|
138
|
+
ctx = XPathContext.new(self)
|
139
|
+
ctx.register_namespaces(ns)
|
140
|
+
set = ctx.evaluate(path, handler).node_set
|
141
|
+
set.document = document
|
142
|
+
document.decorate(set)
|
143
|
+
set
|
144
|
+
}
|
145
|
+
return sets.first if sets.length == 1
|
146
|
+
|
147
|
+
NodeSet.new(document) do |combined|
|
148
|
+
document.decorate(combined)
|
149
|
+
sets.each do |set|
|
150
|
+
set.each do |node|
|
151
|
+
combined << node
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
###
|
158
|
+
# Search this node for CSS +rules+. +rules+ must be one or more CSS
|
159
|
+
# selectors. For example:
|
160
|
+
#
|
161
|
+
# node.css('title')
|
162
|
+
# node.css('body h1.bold')
|
163
|
+
# node.css('div + p.green', 'div#one')
|
164
|
+
#
|
165
|
+
# Custom CSS pseudo classes may also be defined. To define custom pseudo
|
166
|
+
# classes, create a class and implement the custom pseudo class you
|
167
|
+
# want defined. The first argument to the method will be the current
|
168
|
+
# matching NodeSet. Any other arguments are ones that you pass in.
|
169
|
+
# For example:
|
170
|
+
#
|
171
|
+
# node.css('title:regex("\w+")', Class.new {
|
172
|
+
# def regex node_set, regex
|
173
|
+
# node_set.find_all { |node| node['some_attribute'] =~ /#{regex}/ }
|
174
|
+
# end
|
175
|
+
# }.new)
|
176
|
+
#
|
177
|
+
def css *rules
|
178
|
+
# Pop off our custom function handler if it exists
|
179
|
+
handler = ![
|
180
|
+
Hash, String, Symbol
|
181
|
+
].include?(rules.last.class) ? rules.pop : nil
|
182
|
+
|
183
|
+
ns = rules.last.is_a?(Hash) ? rules.pop :
|
184
|
+
(document.root ? document.root.namespaces : {})
|
185
|
+
|
186
|
+
rules = rules.map { |rule|
|
187
|
+
CSS.xpath_for(rule, :prefix => ".//", :ns => ns)
|
188
|
+
}.flatten.uniq + [ns, handler].compact
|
189
|
+
|
190
|
+
xpath(*rules)
|
191
|
+
end
|
192
|
+
|
193
|
+
###
|
194
|
+
# Search for the first occurrence of +path+.
|
195
|
+
# Returns nil if nothing is found, otherwise a Node.
|
196
|
+
def at path, ns = document.root ? document.root.namespaces : {}
|
197
|
+
search(path, ns).first
|
198
|
+
end
|
199
|
+
alias :% :at
|
200
|
+
|
201
|
+
###
|
202
|
+
# Get the attribute value for the attribute +name+
|
203
|
+
def [] name
|
204
|
+
return nil unless key?(name.to_s)
|
205
|
+
get(name.to_s)
|
206
|
+
end
|
207
|
+
|
208
|
+
alias :next :next_sibling
|
209
|
+
alias :previous :previous_sibling
|
210
|
+
alias :remove :unlink
|
211
|
+
alias :get_attribute :[]
|
212
|
+
alias :set_attribute :[]=
|
213
|
+
alias :text :content
|
214
|
+
alias :inner_text :content
|
215
|
+
alias :has_attribute? :key?
|
216
|
+
alias :<< :add_child
|
217
|
+
alias :name :node_name
|
218
|
+
alias :name= :node_name=
|
219
|
+
alias :type :node_type
|
220
|
+
alias :to_str :text
|
221
|
+
alias :clone :dup
|
222
|
+
|
223
|
+
####
|
224
|
+
# Returns a hash containing the node's attributes. The key is the
|
225
|
+
# attribute name, the value is the string value of the attribute.
|
226
|
+
def attributes
|
227
|
+
Hash[*(attribute_nodes.map { |node|
|
228
|
+
[node.node_name, node]
|
229
|
+
}.flatten)]
|
230
|
+
end
|
231
|
+
|
232
|
+
###
|
233
|
+
# Get the attribute values for this Node.
|
234
|
+
def values
|
235
|
+
attribute_nodes.map { |node| node.value }
|
236
|
+
end
|
237
|
+
|
238
|
+
###
|
239
|
+
# Get the attribute names for this Node.
|
240
|
+
def keys
|
241
|
+
attribute_nodes.map { |node| node.node_name }
|
242
|
+
end
|
243
|
+
|
244
|
+
###
|
245
|
+
# Iterate over each attribute name and value pair for this Node.
|
246
|
+
def each &block
|
247
|
+
attribute_nodes.each { |node|
|
248
|
+
block.call(node.node_name, node.value)
|
249
|
+
}
|
250
|
+
end
|
251
|
+
|
252
|
+
###
|
253
|
+
# Remove the attribute named +name+
|
254
|
+
def remove_attribute name
|
255
|
+
attributes[name].remove if key? name
|
256
|
+
end
|
257
|
+
alias :delete :remove_attribute
|
258
|
+
|
259
|
+
###
|
260
|
+
# Returns true if this Node matches +selector+
|
261
|
+
def matches? selector
|
262
|
+
document.search(selector).include?(self)
|
263
|
+
end
|
264
|
+
|
265
|
+
####
|
266
|
+
# Create nodes from +data+ and insert them before this node
|
267
|
+
# (as a sibling).
|
268
|
+
def before data
|
269
|
+
fragment(data).children.each do |node|
|
270
|
+
add_previous_sibling node
|
271
|
+
end
|
272
|
+
self
|
273
|
+
end
|
274
|
+
|
275
|
+
####
|
276
|
+
# Create nodes from +data+ and insert them after this node
|
277
|
+
# (as a sibling).
|
278
|
+
def after data
|
279
|
+
fragment(data).children.to_a.reverse.each do |node|
|
280
|
+
add_next_sibling node
|
281
|
+
end
|
282
|
+
self
|
283
|
+
end
|
284
|
+
|
285
|
+
####
|
286
|
+
# Swap this Node for new nodes made from +data+
|
287
|
+
def swap data
|
288
|
+
before(data)
|
289
|
+
remove
|
290
|
+
self
|
291
|
+
end
|
292
|
+
|
293
|
+
####
|
294
|
+
# Set the inner_html for this Node to +tags+
|
295
|
+
def inner_html= tags
|
296
|
+
children.each { |x| x.remove}
|
297
|
+
|
298
|
+
fragment(tags).children.to_a.reverse.each do |node|
|
299
|
+
add_child node
|
300
|
+
end
|
301
|
+
self
|
302
|
+
end
|
303
|
+
|
304
|
+
def fragment tags # :nodoc:
|
305
|
+
# TODO: deprecate?
|
306
|
+
document.fragment(tags)
|
307
|
+
end
|
308
|
+
|
309
|
+
####
|
310
|
+
# Set the Node content to +string+. The content gets XML escaped.
|
311
|
+
def content= string
|
312
|
+
self.native_content = encode_special_chars(string.to_s)
|
313
|
+
end
|
314
|
+
|
315
|
+
###
|
316
|
+
# Set the parent Node for this Node
|
317
|
+
def parent= parent_node
|
318
|
+
parent_node.add_child(self)
|
319
|
+
parent_node
|
320
|
+
end
|
321
|
+
|
322
|
+
###
|
323
|
+
# Get a hash containing the Namespace definitions for this Node
|
324
|
+
def namespaces
|
325
|
+
Hash[*namespace_definitions.map { |nd|
|
326
|
+
key = ['xmlns', nd.prefix].compact.join(':')
|
327
|
+
if defined?(Encoding) && document.encoding
|
328
|
+
begin
|
329
|
+
key.force_encoding document.encoding
|
330
|
+
rescue ArgumentError
|
331
|
+
end
|
332
|
+
end
|
333
|
+
[key, nd.href]
|
334
|
+
}.flatten]
|
335
|
+
end
|
336
|
+
|
337
|
+
# Returns true if this is a Comment
|
338
|
+
def comment?
|
339
|
+
type == COMMENT_NODE
|
340
|
+
end
|
341
|
+
|
342
|
+
# Returns true if this is a CDATA
|
343
|
+
def cdata?
|
344
|
+
type == CDATA_SECTION_NODE
|
345
|
+
end
|
346
|
+
|
347
|
+
# Returns true if this is an XML::Document node
|
348
|
+
def xml?
|
349
|
+
type == DOCUMENT_NODE
|
350
|
+
end
|
351
|
+
|
352
|
+
# Returns true if this is an HTML::Document node
|
353
|
+
def html?
|
354
|
+
type == HTML_DOCUMENT_NODE
|
355
|
+
end
|
356
|
+
|
357
|
+
# Returns true if this is a Text node
|
358
|
+
def text?
|
359
|
+
type == TEXT_NODE
|
360
|
+
end
|
361
|
+
|
362
|
+
###
|
363
|
+
# Fetch the Nokogiri::HTML::ElementDescription for this node. Returns
|
364
|
+
# nil on XML documents and on unknown tags.
|
365
|
+
def description
|
366
|
+
return nil if document.xml?
|
367
|
+
Nokogiri::HTML::ElementDescription[name]
|
368
|
+
end
|
369
|
+
|
370
|
+
###
|
371
|
+
# Is this a read only node?
|
372
|
+
def read_only?
|
373
|
+
# According to gdome2, these are read-only node types
|
374
|
+
[NOTATION_NODE, ENTITY_NODE, ENTITY_DECL].include?(type)
|
375
|
+
end
|
376
|
+
|
377
|
+
# Returns true if this is an Element node
|
378
|
+
def element?
|
379
|
+
type == ELEMENT_NODE
|
380
|
+
end
|
381
|
+
alias :elem? :element?
|
382
|
+
|
383
|
+
###
|
384
|
+
# Turn this node in to a string. If the document is HTML, this method
|
385
|
+
# returns html. If the document is XML, this method returns XML.
|
386
|
+
def to_s
|
387
|
+
document.xml? ? to_xml : to_html
|
388
|
+
end
|
389
|
+
|
390
|
+
# Get the inner_html for this node's Node#children
|
391
|
+
def inner_html
|
392
|
+
children.map { |x| x.to_html }.join
|
393
|
+
end
|
394
|
+
|
395
|
+
# Get the path to this node as a CSS expression
|
396
|
+
def css_path
|
397
|
+
path.split(/\//).map { |part|
|
398
|
+
part.length == 0 ? nil : part.gsub(/\[(\d+)\]/, ':nth-of-type(\1)')
|
399
|
+
}.compact.join(' > ')
|
400
|
+
end
|
401
|
+
|
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
|
+
###
|
411
|
+
# Get a list of ancestor Node for this Node. If +selector+ is given,
|
412
|
+
# the ancestors must match +selector+
|
413
|
+
def ancestors selector = nil
|
414
|
+
return NodeSet.new(document) unless respond_to?(:parent)
|
415
|
+
return NodeSet.new(document) unless parent
|
416
|
+
|
417
|
+
parents = [parent]
|
418
|
+
|
419
|
+
while parents.last.respond_to?(:parent)
|
420
|
+
break unless ctx_parent = parents.last.parent
|
421
|
+
parents << ctx_parent
|
422
|
+
end
|
423
|
+
|
424
|
+
return NodeSet.new(document, parents) unless selector
|
425
|
+
|
426
|
+
NodeSet.new(document, parents.find_all { |parent|
|
427
|
+
parent.matches?(selector)
|
428
|
+
})
|
429
|
+
end
|
430
|
+
|
431
|
+
###
|
432
|
+
# Set the default namespace for this node to +url+
|
433
|
+
def default_namespace= url
|
434
|
+
add_namespace_definition(nil, url)
|
435
|
+
end
|
436
|
+
alias :add_namespace :add_namespace_definition
|
437
|
+
|
438
|
+
###
|
439
|
+
# Set the namespace for this node to +ns+
|
440
|
+
def namespace= ns
|
441
|
+
if ns.document != document
|
442
|
+
raise ArgumentError, 'namespace must be declared on the same document'
|
443
|
+
end
|
444
|
+
unless ns.is_a? Nokogiri::XML::Namespace
|
445
|
+
raise TypeError, "#{ns.class} can't be coerced into Nokogiri::XML::Namespace"
|
446
|
+
end
|
447
|
+
set_namespace ns
|
448
|
+
end
|
449
|
+
|
450
|
+
####
|
451
|
+
# Yields self and all children to +block+ recursively.
|
452
|
+
def traverse &block
|
453
|
+
children.each{|j| j.traverse(&block) }
|
454
|
+
block.call(self)
|
455
|
+
end
|
456
|
+
|
457
|
+
###
|
458
|
+
# Accept a visitor. This method calls "visit" on +visitor+ with self.
|
459
|
+
def accept visitor
|
460
|
+
visitor.visit(self)
|
461
|
+
end
|
462
|
+
|
463
|
+
####
|
464
|
+
# replace this Node with the +new_node+ in the Document.
|
465
|
+
def replace(new_node)
|
466
|
+
if new_node.is_a?(Document) || !new_node.is_a?(XML::Node)
|
467
|
+
raise ArgumentError, <<-EOERR
|
468
|
+
Node.replace requires a Node argument, and cannot accept a Document.
|
469
|
+
(You probably want to select a node from the Document with at() or search(), or create a new Node via Node.new().)
|
470
|
+
EOERR
|
471
|
+
end
|
472
|
+
replace_with_node new_node
|
473
|
+
end
|
474
|
+
|
475
|
+
###
|
476
|
+
# Test to see if this Node is equal to +other+
|
477
|
+
def == other
|
478
|
+
return false unless other
|
479
|
+
return false unless other.respond_to?(:pointer_id)
|
480
|
+
pointer_id == other.pointer_id
|
481
|
+
end
|
482
|
+
|
483
|
+
###
|
484
|
+
# Serialize Node using +options+. Save options
|
485
|
+
# can also be set using a block. See SaveOptions.
|
486
|
+
#
|
487
|
+
# These two statements are equivalent:
|
488
|
+
#
|
489
|
+
# node.serialize(:encoding => 'UTF-8', :save_with => FORMAT | AS_XML)
|
490
|
+
#
|
491
|
+
# or
|
492
|
+
#
|
493
|
+
# node.serialize(:encoding => 'UTF-8') do |config|
|
494
|
+
# config.format.as_xml
|
495
|
+
# end
|
496
|
+
#
|
497
|
+
def serialize *args, &block
|
498
|
+
if args.first && !args.first.is_a?(Hash)
|
499
|
+
$stderr.puts(<<-eowarn)
|
500
|
+
#{self.class}#serialize(encoding, save_opts) is deprecated and will be removed in
|
501
|
+
Nokogiri version 1.4.0 *or* after June 1 2009.
|
502
|
+
You called serialize from here:
|
503
|
+
|
504
|
+
#{caller.first}
|
505
|
+
|
506
|
+
Please change to #{self.class}#serialize(:encoding => enc, :save_with => opts)
|
507
|
+
eowarn
|
508
|
+
end
|
509
|
+
|
510
|
+
options = args.first.is_a?(Hash) ? args.shift : {
|
511
|
+
:encoding => args[0],
|
512
|
+
:save_with => args[1] || SaveOptions::FORMAT
|
513
|
+
}
|
514
|
+
|
515
|
+
io = StringIO.new
|
516
|
+
write_to io, options, &block
|
517
|
+
io.rewind
|
518
|
+
io.read
|
519
|
+
end
|
520
|
+
|
521
|
+
###
|
522
|
+
# Serialize this Node to HTML
|
523
|
+
#
|
524
|
+
# doc.to_html
|
525
|
+
#
|
526
|
+
# See Node#write_to for a list of +options+. For formatted output,
|
527
|
+
# use Node#to_xhtml instead.
|
528
|
+
def to_html options = {}
|
529
|
+
if options.is_a?(String)
|
530
|
+
$stderr.puts(<<-eowarn)
|
531
|
+
Node#to_html(encoding) is deprecated and will be removed in
|
532
|
+
Nokogiri version 1.4.0 *or* after June 1 2009.
|
533
|
+
You called to_html from here:
|
534
|
+
|
535
|
+
#{caller.first}
|
536
|
+
|
537
|
+
Please change to Node#to_html(:encoding => #{options})
|
538
|
+
eowarn
|
539
|
+
options = { :encoding => options }
|
540
|
+
end
|
541
|
+
|
542
|
+
# FIXME: this is a hack around broken libxml versions
|
543
|
+
return dump_html if %w[2 6] === LIBXML_VERSION.split('.')[0..1]
|
544
|
+
|
545
|
+
options[:save_with] ||= SaveOptions::FORMAT |
|
546
|
+
SaveOptions::NO_DECLARATION |
|
547
|
+
SaveOptions::NO_EMPTY_TAGS |
|
548
|
+
SaveOptions::AS_HTML
|
549
|
+
|
550
|
+
serialize(options)
|
551
|
+
end
|
552
|
+
|
553
|
+
###
|
554
|
+
# Serialize this Node to XML using +options+
|
555
|
+
#
|
556
|
+
# doc.to_xml(:indent => 5, :encoding => 'UTF-8')
|
557
|
+
#
|
558
|
+
# See Node#write_to for a list of +options+
|
559
|
+
def to_xml options = {}
|
560
|
+
encoding = nil
|
561
|
+
|
562
|
+
# FIXME add a deprecation warning
|
563
|
+
if options.is_a? String
|
564
|
+
$stderr.puts(<<-eowarn)
|
565
|
+
Node#to_xml(encoding) is deprecated and will be removed in
|
566
|
+
Nokogiri version 1.4.0 *or* after June 1 2009.
|
567
|
+
You called to_xml from here:
|
568
|
+
|
569
|
+
#{caller.first}
|
570
|
+
|
571
|
+
Please change to Node#to_xml(:encoding => #{options})
|
572
|
+
eowarn
|
573
|
+
options = {
|
574
|
+
:encoding => options
|
575
|
+
}
|
576
|
+
end
|
577
|
+
options[:save_with] ||= SaveOptions::FORMAT | SaveOptions::AS_XML
|
578
|
+
|
579
|
+
serialize(options)
|
580
|
+
end
|
581
|
+
|
582
|
+
###
|
583
|
+
# Serialize this Node to XHTML using +options+
|
584
|
+
#
|
585
|
+
# doc.to_xhtml(:indent => 5, :encoding => 'UTF-8')
|
586
|
+
#
|
587
|
+
# See Node#write_to for a list of +options+
|
588
|
+
def to_xhtml options = {}
|
589
|
+
if options.is_a?(String)
|
590
|
+
options = { :encoding => options }
|
591
|
+
$stderr.puts(<<-eowarn)
|
592
|
+
Node#to_xml(encoding) is deprecated and will be removed in
|
593
|
+
Nokogiri version 1.4.0 *or* after June 1 2009.
|
594
|
+
You called to_xhtml from here:
|
595
|
+
|
596
|
+
#{caller.first}
|
597
|
+
|
598
|
+
Please change to Node#to_xhtml(:encoding => #{options})
|
599
|
+
eowarn
|
600
|
+
end
|
601
|
+
|
602
|
+
# FIXME: this is a hack around broken libxml versions
|
603
|
+
return dump_html if %w[2 6] === LIBXML_VERSION.split('.')[0..1]
|
604
|
+
|
605
|
+
options[:save_with] ||= SaveOptions::FORMAT |
|
606
|
+
SaveOptions::NO_DECLARATION |
|
607
|
+
SaveOptions::NO_EMPTY_TAGS |
|
608
|
+
SaveOptions::AS_XHTML
|
609
|
+
|
610
|
+
serialize(options)
|
611
|
+
end
|
612
|
+
|
613
|
+
###
|
614
|
+
# Write Node to +io+ with +options+. +options+ modify the output of
|
615
|
+
# this method. Valid options are:
|
616
|
+
#
|
617
|
+
# * +:encoding+ for changing the encoding
|
618
|
+
# * +:indent_text+ the indentation text, defaults to one space
|
619
|
+
# * +:indent+ the number of +:indent_text+ to use, defaults to 2
|
620
|
+
# * +:save_with+ a combination of SaveOptions constants.
|
621
|
+
#
|
622
|
+
# To save with UTF-8 indented twice:
|
623
|
+
#
|
624
|
+
# node.write_to(io, :encoding => 'UTF-8', :indent => 2)
|
625
|
+
#
|
626
|
+
# To save indented with two dashes:
|
627
|
+
#
|
628
|
+
# node.write_to(io, :indent_text => '-', :indent => 2
|
629
|
+
#
|
630
|
+
def write_to io, *options
|
631
|
+
if options.length > 0 && !options.first.is_a?(Hash)
|
632
|
+
$stderr.puts(<<-eowarn)
|
633
|
+
Node#write_to(io, encoding, save_options) is deprecated and will be removed in
|
634
|
+
Nokogiri version 1.4.0 *or* after June 1 2009.
|
635
|
+
You called write_to from here:
|
636
|
+
|
637
|
+
#{caller.first}
|
638
|
+
|
639
|
+
Please change to: Node#write_to(io, :encoding => e, :save_options => opts)
|
640
|
+
eowarn
|
641
|
+
end
|
642
|
+
|
643
|
+
options = options.first.is_a?(Hash) ? options.shift : {}
|
644
|
+
encoding = options[:encoding] || options[0]
|
645
|
+
save_options = options[:save_with] || options[1] || SaveOptions::FORMAT
|
646
|
+
indent_text = options[:indent_text] || ' '
|
647
|
+
indent_times = options[:indent] || 2
|
648
|
+
|
649
|
+
|
650
|
+
config = SaveOptions.new(save_options)
|
651
|
+
yield config if block_given?
|
652
|
+
|
653
|
+
native_write_to(io, encoding, indent_text * indent_times, config.options)
|
654
|
+
end
|
655
|
+
|
656
|
+
###
|
657
|
+
# Write Node as HTML to +io+ with +options+
|
658
|
+
#
|
659
|
+
# See Node#write_to for a list of +options+
|
660
|
+
def write_html_to io, options = {}
|
661
|
+
if options.is_a?(String)
|
662
|
+
$stderr.puts(<<-eowarn)
|
663
|
+
Node#write_html_to(io, encoding) is deprecated and will be removed in
|
664
|
+
Nokogiri version 1.4.0 *or* after June 1 2009.
|
665
|
+
You called write_html_to from here:
|
666
|
+
|
667
|
+
#{caller.first}
|
668
|
+
|
669
|
+
Please change to Node#write_html_to(io, :encoding => #{options})
|
670
|
+
eowarn
|
671
|
+
options = { :encoding => options }
|
672
|
+
end
|
673
|
+
|
674
|
+
# FIXME: this is a hack around broken libxml versions
|
675
|
+
return (io << dump_html) if %w[2 6] === LIBXML_VERSION.split('.')[0..1]
|
676
|
+
|
677
|
+
options[:save_with] ||= SaveOptions::FORMAT |
|
678
|
+
SaveOptions::NO_DECLARATION |
|
679
|
+
SaveOptions::NO_EMPTY_TAGS |
|
680
|
+
SaveOptions::AS_HTML
|
681
|
+
write_to io, options
|
682
|
+
end
|
683
|
+
|
684
|
+
###
|
685
|
+
# Write Node as XHTML to +io+ with +options+
|
686
|
+
#
|
687
|
+
# See Node#write_to for a list of +options+
|
688
|
+
def write_xhtml_to io, options = {}
|
689
|
+
if options.is_a?(String)
|
690
|
+
$stderr.puts(<<-eowarn)
|
691
|
+
Node#write_xhtml_to(io, encoding) is deprecated and will be removed in
|
692
|
+
Nokogiri version 1.4.0 *or* after June 1 2009.
|
693
|
+
You called write_xhtml_to from here:
|
694
|
+
|
695
|
+
#{caller.first}
|
696
|
+
|
697
|
+
Please change to Node#write_xhtml_to(io, :encoding => #{options})
|
698
|
+
eowarn
|
699
|
+
options = { :encoding => options }
|
700
|
+
end
|
701
|
+
|
702
|
+
# FIXME: this is a hack around broken libxml versions
|
703
|
+
return (io << dump_html) if %w[2 6] === LIBXML_VERSION.split('.')[0..1]
|
704
|
+
|
705
|
+
options[:save_with] ||= SaveOptions::FORMAT |
|
706
|
+
SaveOptions::NO_DECLARATION |
|
707
|
+
SaveOptions::NO_EMPTY_TAGS |
|
708
|
+
SaveOptions::AS_XHTML
|
709
|
+
write_to io, options
|
710
|
+
end
|
711
|
+
|
712
|
+
###
|
713
|
+
# Write Node as XML to +io+ with +options+
|
714
|
+
#
|
715
|
+
# doc.write_xml_to io, :encoding => 'UTF-8'
|
716
|
+
#
|
717
|
+
# See Node#write_to for a list of options
|
718
|
+
def write_xml_to io, options = {}
|
719
|
+
if options.is_a?(String)
|
720
|
+
$stderr.puts(<<-eowarn)
|
721
|
+
Node#write_xml_to(io, encoding) is deprecated and will be removed in
|
722
|
+
Nokogiri version 1.4.0 *or* after June 1 2009.
|
723
|
+
You called write_xml_to from here:
|
724
|
+
|
725
|
+
#{caller.first}
|
726
|
+
|
727
|
+
Please change to Node#write_xml_to(io, :encoding => #{options})
|
728
|
+
eowarn
|
729
|
+
options = { :encoding => options }
|
730
|
+
end
|
731
|
+
options[:save_with] ||= SaveOptions::FORMAT | SaveOptions::AS_XML
|
732
|
+
write_to io, options
|
733
|
+
end
|
734
|
+
|
735
|
+
###
|
736
|
+
# Compare two Node objects with respect to their Document. Nodes from
|
737
|
+
# different documents cannot be compared.
|
738
|
+
def <=> other
|
739
|
+
return nil unless other.is_a?(Nokogiri::XML::Node)
|
740
|
+
return nil unless document == other.document
|
741
|
+
compare other
|
742
|
+
end
|
743
|
+
end
|
744
|
+
end
|
745
|
+
end
|