nokogiri 1.3.3-java → 1.4.0-java
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/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 +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/ext/nokogiri/zlib1.dll +0 -0
- data/lib/nokogiri.rb +4 -4
- 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 +100 -78
- 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
@@ -1,11 +1,11 @@
|
|
1
1
|
module Nokogiri
|
2
2
|
module XML
|
3
|
-
class Text <
|
3
|
+
class Text < CharacterData
|
4
4
|
|
5
5
|
def self.new(string, document, *rest) # :nodoc:
|
6
6
|
node_ptr = LibXML.xmlNewText(string)
|
7
7
|
node_cstruct = LibXML::XmlNode.new(node_ptr)
|
8
|
-
node_cstruct[:doc] = document.cstruct
|
8
|
+
node_cstruct[:doc] = document.cstruct[:doc]
|
9
9
|
|
10
10
|
node = Node.wrap(node_cstruct, self)
|
11
11
|
node.send :initialize, string, document, *rest
|
data/lib/nokogiri/html.rb
CHANGED
@@ -1,39 +1,54 @@
|
|
1
1
|
module Nokogiri
|
2
2
|
module HTML
|
3
3
|
class Document < Nokogiri::XML::Document
|
4
|
+
###
|
5
|
+
# Get the meta tag encoding for this document. If there is no meta tag,
|
6
|
+
# then nil is returned
|
7
|
+
def meta_encoding
|
8
|
+
return nil unless meta = css('meta').find { |node|
|
9
|
+
node['http-equiv'] =~ /Content-Type/i
|
10
|
+
}
|
4
11
|
|
5
|
-
|
6
|
-
super
|
12
|
+
/charset\s*=\s*([\w\d-]+)/i.match(meta['content'])[1]
|
7
13
|
end
|
8
14
|
|
9
|
-
|
10
|
-
#
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
You called serialize from here:
|
17
|
-
|
18
|
-
#{caller.join("\n")}
|
15
|
+
###
|
16
|
+
# Set the meta tag encoding for this document. If there is no meta
|
17
|
+
# content tag, nil is returned and the encoding is not set.
|
18
|
+
def meta_encoding= encoding
|
19
|
+
return nil unless meta = css('meta').find { |node|
|
20
|
+
node['http-equiv'] =~ /Content-Type/i
|
21
|
+
}
|
19
22
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
+
meta['content'] = "text/html; charset=%s" % encoding
|
24
|
+
encoding
|
25
|
+
end
|
23
26
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
+
####
|
28
|
+
# Serialize Node using +options+. Save options can also be set using a
|
29
|
+
# block. See SaveOptions.
|
30
|
+
#
|
31
|
+
# These two statements are equivalent:
|
32
|
+
#
|
33
|
+
# node.serialize(:encoding => 'UTF-8', :save_with => FORMAT | AS_XML)
|
34
|
+
#
|
35
|
+
# or
|
36
|
+
#
|
37
|
+
# node.serialize(:encoding => 'UTF-8') do |config|
|
38
|
+
# config.format.as_xml
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
def serialize options = {}, &block
|
42
|
+
options[:save_with] ||= XML::Node::SaveOptions::FORMAT |
|
27
43
|
XML::Node::SaveOptions::AS_HTML |
|
28
44
|
XML::Node::SaveOptions::NO_DECLARATION |
|
29
45
|
XML::Node::SaveOptions::NO_EMPTY_TAGS
|
30
|
-
|
31
|
-
super(options)
|
46
|
+
super
|
32
47
|
end
|
33
48
|
|
34
49
|
####
|
35
50
|
# Create a Nokogiri::XML::DocumentFragment from +tags+
|
36
|
-
def fragment tags
|
51
|
+
def fragment tags = nil
|
37
52
|
DocumentFragment.new(self, tags)
|
38
53
|
end
|
39
54
|
|
@@ -58,13 +73,13 @@ Please change to #{self.class}#serialize(:encoding => enc, :save_with => opts)
|
|
58
73
|
|
59
74
|
if string_or_io.respond_to?(:read)
|
60
75
|
url ||= string_or_io.respond_to?(:path) ? string_or_io.path : nil
|
61
|
-
return
|
76
|
+
return read_io(string_or_io, url, encoding, options.to_i)
|
62
77
|
end
|
63
78
|
|
64
79
|
# read_memory pukes on empty docs
|
65
|
-
return
|
80
|
+
return new if string_or_io.nil? or string_or_io.empty?
|
66
81
|
|
67
|
-
|
82
|
+
read_memory(string_or_io, url, encoding, options.to_i)
|
68
83
|
end
|
69
84
|
end
|
70
85
|
|
@@ -31,7 +31,7 @@ module Nokogiri
|
|
31
31
|
def parse_memory data, encoding = 'UTF-8'
|
32
32
|
raise ArgumentError unless data
|
33
33
|
return unless data.length > 0
|
34
|
-
|
34
|
+
ParserContext.memory(data, encoding).parse_with self
|
35
35
|
end
|
36
36
|
|
37
37
|
###
|
@@ -40,7 +40,7 @@ module Nokogiri
|
|
40
40
|
raise ArgumentError unless filename
|
41
41
|
raise Errno::ENOENT unless File.exists?(filename)
|
42
42
|
raise Errno::EISDIR if File.directory?(filename)
|
43
|
-
|
43
|
+
ParserContext.file(filename, encoding).parse_with self
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Nokogiri
|
2
|
+
module HTML
|
3
|
+
module SAX
|
4
|
+
###
|
5
|
+
# Context for HTML SAX parsers. This class is usually not instantiated
|
6
|
+
# by the user. Instead, you should be looking at
|
7
|
+
# Nokogiri::HTML::SAX::Parser
|
8
|
+
class ParserContext < Nokogiri::XML::SAX::ParserContext
|
9
|
+
def self.new thing, encoding = 'UTF-8'
|
10
|
+
[:read, :close].all? { |x| thing.respond_to?(x) } ? super :
|
11
|
+
memory(thing, encoding)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/nokogiri/version.rb
CHANGED
data/lib/nokogiri/xml.rb
CHANGED
@@ -1,7 +1,12 @@
|
|
1
|
+
require 'nokogiri/xml/pp'
|
1
2
|
require 'nokogiri/xml/parse_options'
|
2
3
|
require 'nokogiri/xml/sax'
|
3
4
|
require 'nokogiri/xml/fragment_handler'
|
4
5
|
require 'nokogiri/xml/node'
|
6
|
+
require 'nokogiri/xml/attribute_decl'
|
7
|
+
require 'nokogiri/xml/element_decl'
|
8
|
+
require 'nokogiri/xml/element_content'
|
9
|
+
require 'nokogiri/xml/character_data'
|
5
10
|
require 'nokogiri/xml/namespace'
|
6
11
|
require 'nokogiri/xml/attr'
|
7
12
|
require 'nokogiri/xml/dtd'
|
@@ -16,7 +21,7 @@ require 'nokogiri/xml/xpath_context'
|
|
16
21
|
require 'nokogiri/xml/builder'
|
17
22
|
require 'nokogiri/xml/reader'
|
18
23
|
require 'nokogiri/xml/notation'
|
19
|
-
require 'nokogiri/xml/
|
24
|
+
require 'nokogiri/xml/entity_decl'
|
20
25
|
require 'nokogiri/xml/schema'
|
21
26
|
require 'nokogiri/xml/relax_ng'
|
22
27
|
|
data/lib/nokogiri/xml/attr.rb
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Nokogiri
|
2
|
+
module XML
|
3
|
+
###
|
4
|
+
# Represents an attribute declaration in a DTD
|
5
|
+
class AttributeDecl < Nokogiri::XML::Node
|
6
|
+
undef_method :attribute_nodes
|
7
|
+
undef_method :attributes
|
8
|
+
undef_method :content
|
9
|
+
undef_method :namespace
|
10
|
+
undef_method :namespace_definitions
|
11
|
+
undef_method :line
|
12
|
+
|
13
|
+
def inspect
|
14
|
+
"#<#{self.class.name}:#{sprintf("0x%x", object_id)} #{to_s.inspect}>"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/nokogiri/xml/builder.rb
CHANGED
@@ -147,6 +147,53 @@ module Nokogiri
|
|
147
147
|
#
|
148
148
|
# All other options are still supported with this syntax, including
|
149
149
|
# blocks and extra tag attributes.
|
150
|
+
#
|
151
|
+
# == Namespaces
|
152
|
+
#
|
153
|
+
# Namespaces are added similarly to attributes. Nokogiri::XML::Builder
|
154
|
+
# assumes that when an attribute starts with "xmlns", it is meant to be
|
155
|
+
# a namespace:
|
156
|
+
#
|
157
|
+
# builder = Nokogiri::XML::Builder.new { |xml|
|
158
|
+
# xml.root('xmlns' => 'default', 'xmlns:foo' => 'bar') do
|
159
|
+
# xml.tenderlove
|
160
|
+
# end
|
161
|
+
# }
|
162
|
+
# puts builder.to_xml
|
163
|
+
#
|
164
|
+
# Will output XML like this:
|
165
|
+
#
|
166
|
+
# <?xml version="1.0"?>
|
167
|
+
# <root xmlns:foo="bar" xmlns="default">
|
168
|
+
# <tenderlove/>
|
169
|
+
# </root>
|
170
|
+
#
|
171
|
+
# === Referencing declared namespaces
|
172
|
+
#
|
173
|
+
# Tags that reference non-default namespaces (i.e. a tag "foo:bar") can be
|
174
|
+
# built by using the Nokogiri::XML::Builder#[] method.
|
175
|
+
#
|
176
|
+
# For example:
|
177
|
+
#
|
178
|
+
# builder = Nokogiri::XML::Builder.new do |xml|
|
179
|
+
# xml.root('xmlns:foo' => 'bar') {
|
180
|
+
# xml.objects {
|
181
|
+
# xml['foo'].object.classy.thing!
|
182
|
+
# }
|
183
|
+
# }
|
184
|
+
# end
|
185
|
+
# puts builder.to_xml
|
186
|
+
#
|
187
|
+
# Will output this XML:
|
188
|
+
#
|
189
|
+
# <?xml version="1.0"?>
|
190
|
+
# <root xmlns:foo="bar">
|
191
|
+
# <objects>
|
192
|
+
# <foo:object class="classy" id="thing"/>
|
193
|
+
# </objects>
|
194
|
+
# </root>
|
195
|
+
#
|
196
|
+
# Note the "foo:object" tag.
|
150
197
|
class Builder
|
151
198
|
# The current Document object being built
|
152
199
|
attr_accessor :doc
|
@@ -159,6 +206,24 @@ module Nokogiri
|
|
159
206
|
|
160
207
|
attr_accessor :arity # :nodoc:
|
161
208
|
|
209
|
+
###
|
210
|
+
# Create a builder with an existing root object. This is for use when
|
211
|
+
# you have an existing document that you would like to augment with
|
212
|
+
# builder methods. The builder context created will start with the
|
213
|
+
# given +root+ node.
|
214
|
+
#
|
215
|
+
# For example:
|
216
|
+
#
|
217
|
+
# doc = Nokogiri::XML(open('somedoc.xml'))
|
218
|
+
# Nokogiri::XML::Builder.with(doc.at('some_tag')) do |xml|
|
219
|
+
# # ... Use normal builder methods here ...
|
220
|
+
# xml.awesome # add the "awesome" tag below "some_tag"
|
221
|
+
# end
|
222
|
+
#
|
223
|
+
def self.with root, &block
|
224
|
+
builder = self.new({}, root, &block)
|
225
|
+
end
|
226
|
+
|
162
227
|
###
|
163
228
|
# Create a new Builder object. +options+ are sent to the top level
|
164
229
|
# Document that is being built.
|
@@ -168,13 +233,21 @@ module Nokogiri
|
|
168
233
|
# Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
|
169
234
|
# ...
|
170
235
|
# end
|
171
|
-
def initialize options = {}, &block
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
236
|
+
def initialize options = {}, root = nil, &block
|
237
|
+
|
238
|
+
if root
|
239
|
+
@doc = root.document
|
240
|
+
@parent = root
|
241
|
+
else
|
242
|
+
namespace = self.class.name.split('::')
|
243
|
+
namespace[-1] = 'Document'
|
244
|
+
@doc = eval(namespace.join('::')).new
|
245
|
+
@parent = @doc
|
246
|
+
end
|
247
|
+
|
176
248
|
@context = nil
|
177
249
|
@arity = nil
|
250
|
+
@ns = nil
|
178
251
|
|
179
252
|
options.each do |k,v|
|
180
253
|
@doc.send(:"#{k}=", v)
|
@@ -196,8 +269,7 @@ module Nokogiri
|
|
196
269
|
###
|
197
270
|
# Create a Text Node with content of +string+
|
198
271
|
def text string
|
199
|
-
|
200
|
-
insert(node)
|
272
|
+
insert @doc.create_text_node string
|
201
273
|
end
|
202
274
|
|
203
275
|
###
|
@@ -207,21 +279,57 @@ module Nokogiri
|
|
207
279
|
insert(node)
|
208
280
|
end
|
209
281
|
|
282
|
+
###
|
283
|
+
# Build a tag that is associated with namespace +ns+. Raises an
|
284
|
+
# ArgumentError if +ns+ has not been defined higher in the tree.
|
285
|
+
def [] ns
|
286
|
+
@ns = @parent.namespace_definitions.find { |x| x.prefix == ns.to_s }
|
287
|
+
return self if @ns
|
288
|
+
|
289
|
+
@parent.ancestors.each do |a|
|
290
|
+
next if a == doc
|
291
|
+
@ns = a.namespace_definitions.find { |x| x.prefix == ns.to_s }
|
292
|
+
return self if @ns
|
293
|
+
end
|
294
|
+
|
295
|
+
raise ArgumentError, "Namespace #{ns} has not been defined"
|
296
|
+
end
|
297
|
+
|
210
298
|
###
|
211
299
|
# Convert this Builder object to XML
|
212
|
-
def to_xml
|
213
|
-
@doc.to_xml
|
300
|
+
def to_xml(*args)
|
301
|
+
@doc.to_xml(*args)
|
302
|
+
end
|
303
|
+
|
304
|
+
###
|
305
|
+
# Append the given raw XML +string+ to the document
|
306
|
+
def << string
|
307
|
+
@doc.fragment(string).children.each { |x| insert(x) }
|
214
308
|
end
|
215
309
|
|
216
310
|
def method_missing method, *args, &block # :nodoc:
|
217
311
|
if @context && @context.respond_to?(method)
|
218
312
|
@context.send(method, *args, &block)
|
219
313
|
else
|
220
|
-
node =
|
314
|
+
node = @doc.create_element(method.to_s.sub(/[_!]$/, '')) { |n|
|
315
|
+
# Set up the namespace
|
316
|
+
if @ns
|
317
|
+
n.namespace = @ns
|
318
|
+
@ns = nil
|
319
|
+
end
|
320
|
+
|
221
321
|
args.each do |arg|
|
222
322
|
case arg
|
223
323
|
when Hash
|
224
|
-
arg.each { |k,v|
|
324
|
+
arg.each { |k,v|
|
325
|
+
key = k.to_s
|
326
|
+
if key =~ /^xmlns(:\w+)?$/
|
327
|
+
ns_name = key.split(":", 2)[1]
|
328
|
+
n.add_namespace_definition ns_name, v
|
329
|
+
next
|
330
|
+
end
|
331
|
+
n[k.to_s] = v.to_s
|
332
|
+
}
|
225
333
|
else
|
226
334
|
n.content = arg
|
227
335
|
end
|
@@ -250,7 +358,7 @@ module Nokogiri
|
|
250
358
|
end
|
251
359
|
|
252
360
|
class NodeBuilder # :nodoc:
|
253
|
-
def initialize
|
361
|
+
def initialize node, doc_builder
|
254
362
|
@node = node
|
255
363
|
@doc_builder = doc_builder
|
256
364
|
end
|
@@ -272,7 +380,7 @@ module Nokogiri
|
|
272
380
|
when /^(.*)=/
|
273
381
|
@node[$1] = args.first
|
274
382
|
else
|
275
|
-
@node['class'] =
|
383
|
+
@node['class'] =
|
276
384
|
((@node['class'] || '').split(/\s/) + [method.to_s]).join(' ')
|
277
385
|
@node.content = args.first if args.first
|
278
386
|
end
|
@@ -8,6 +8,31 @@ module Nokogiri
|
|
8
8
|
# For searching a Document, see Nokogiri::XML::Node#css and
|
9
9
|
# Nokogiri::XML::Node#xpath
|
10
10
|
class Document < Node
|
11
|
+
###
|
12
|
+
# Parse an XML file. +thing+ may be a String, or any object that
|
13
|
+
# responds to _read_ and _close_ such as an IO, or StringIO.
|
14
|
+
# +url+ is resource where this document is located. +encoding+ is the
|
15
|
+
# encoding that should be used when processing the document. +options+
|
16
|
+
# is a number that sets options in the parser, such as
|
17
|
+
# Nokogiri::XML::ParseOptions::RECOVER. See the constants in
|
18
|
+
# Nokogiri::XML::ParseOptions.
|
19
|
+
def self.parse string_or_io, url = nil, encoding = nil, options = ParseOptions::DEFAULT_XML, &block
|
20
|
+
|
21
|
+
options = Nokogiri::XML::ParseOptions.new(options) if Fixnum === options
|
22
|
+
# Give the options to the user
|
23
|
+
yield options if block_given?
|
24
|
+
|
25
|
+
if string_or_io.respond_to?(:read)
|
26
|
+
url ||= string_or_io.respond_to?(:path) ? string_or_io.path : nil
|
27
|
+
return read_io(string_or_io, url, encoding, options.to_i)
|
28
|
+
end
|
29
|
+
|
30
|
+
# read_memory pukes on empty docs
|
31
|
+
return new if string_or_io.nil? or string_or_io.empty?
|
32
|
+
|
33
|
+
read_memory(string_or_io, url, encoding, options.to_i)
|
34
|
+
end
|
35
|
+
|
11
36
|
# A list of Nokogiri::XML::SyntaxError found when parsing a document
|
12
37
|
attr_accessor :errors
|
13
38
|
|
@@ -15,6 +40,16 @@ module Nokogiri
|
|
15
40
|
@decorators = nil
|
16
41
|
end
|
17
42
|
|
43
|
+
# Create an element with +name+
|
44
|
+
def create_element name, &block
|
45
|
+
Nokogiri::XML::Element.new(name, self, &block)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Create a text node with +text+
|
49
|
+
def create_text_node text, &block
|
50
|
+
Nokogiri::XML::Text.new(text.to_s, self, &block)
|
51
|
+
end
|
52
|
+
|
18
53
|
# The name of this document. Always returns "document"
|
19
54
|
def name
|
20
55
|
'document'
|
@@ -65,17 +100,19 @@ module Nokogiri
|
|
65
100
|
|
66
101
|
# Get the hash of namespaces on the root Nokogiri::XML::Node
|
67
102
|
def namespaces
|
68
|
-
root ? root.
|
103
|
+
root ? root.namespaces : {}
|
69
104
|
end
|
70
105
|
|
71
106
|
####
|
72
107
|
# Create a Nokogiri::XML::DocumentFragment from +tags+
|
73
|
-
|
108
|
+
# Returns an empty fragment if +tags+ is nil.
|
109
|
+
def fragment tags = nil
|
74
110
|
DocumentFragment.new(self, tags)
|
75
111
|
end
|
76
112
|
|
77
113
|
undef_method :swap, :parent, :namespace, :default_namespace=
|
78
|
-
undef_method :add_namespace_definition
|
114
|
+
undef_method :add_namespace_definition, :attributes
|
115
|
+
undef_method :namespace_definitions, :line
|
79
116
|
|
80
117
|
def add_child child
|
81
118
|
if [Node::ELEMENT_NODE, Node::DOCUMENT_FRAG_NODE].include? child.type
|
@@ -85,33 +122,10 @@ module Nokogiri
|
|
85
122
|
end
|
86
123
|
alias :<< :add_child
|
87
124
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
# responds to _read_ and _close_ such as an IO, or StringIO.
|
92
|
-
# +url+ is resource where this document is located. +encoding+ is the
|
93
|
-
# encoding that should be used when processing the document. +options+
|
94
|
-
# is a number that sets options in the parser, such as
|
95
|
-
# Nokogiri::XML::ParseOptions::RECOVER. See the constants in
|
96
|
-
# Nokogiri::XML::ParseOptions.
|
97
|
-
def parse string_or_io, url = nil, encoding = nil, options = ParseOptions::DEFAULT_XML, &block
|
98
|
-
|
99
|
-
options = Nokogiri::XML::ParseOptions.new(options) if Fixnum === options
|
100
|
-
# Give the options to the user
|
101
|
-
yield options if block_given?
|
102
|
-
|
103
|
-
if string_or_io.respond_to?(:read)
|
104
|
-
url ||= string_or_io.respond_to?(:path) ? string_or_io.path : nil
|
105
|
-
return self.read_io(string_or_io, url, encoding, options.to_i)
|
106
|
-
end
|
107
|
-
|
108
|
-
# read_memory pukes on empty docs
|
109
|
-
return self.new if string_or_io.nil? or string_or_io.empty?
|
110
|
-
|
111
|
-
self.read_memory(string_or_io, url, encoding, options.to_i)
|
112
|
-
end
|
125
|
+
private
|
126
|
+
def inspect_attributes
|
127
|
+
[:name, :children]
|
113
128
|
end
|
114
|
-
|
115
129
|
end
|
116
130
|
end
|
117
131
|
end
|