nokogiri 1.2.3 → 1.3.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.

Files changed (200) hide show
  1. data/.autotest +14 -2
  2. data/CHANGELOG.ja.rdoc +38 -0
  3. data/CHANGELOG.rdoc +43 -0
  4. data/Manifest.txt +80 -5
  5. data/README.ja.rdoc +12 -11
  6. data/README.rdoc +4 -2
  7. data/Rakefile +103 -173
  8. data/bin/nokogiri +47 -0
  9. data/ext/nokogiri/extconf.rb +19 -13
  10. data/ext/nokogiri/html_document.c +39 -3
  11. data/ext/nokogiri/html_document.h +1 -1
  12. data/ext/nokogiri/html_element_description.c +272 -0
  13. data/ext/nokogiri/html_element_description.h +10 -0
  14. data/ext/nokogiri/html_entity_lookup.h +1 -1
  15. data/ext/nokogiri/html_sax_parser.h +1 -1
  16. data/ext/nokogiri/{native.c → nokogiri.c} +11 -3
  17. data/ext/nokogiri/{native.h → nokogiri.h} +18 -4
  18. data/ext/nokogiri/xml_attr.c +14 -5
  19. data/ext/nokogiri/xml_attr.h +1 -1
  20. data/ext/nokogiri/xml_cdata.c +15 -6
  21. data/ext/nokogiri/xml_cdata.h +1 -1
  22. data/ext/nokogiri/xml_comment.c +13 -4
  23. data/ext/nokogiri/xml_comment.h +1 -1
  24. data/ext/nokogiri/xml_document.c +50 -41
  25. data/ext/nokogiri/xml_document.h +1 -1
  26. data/ext/nokogiri/xml_document_fragment.c +12 -4
  27. data/ext/nokogiri/xml_document_fragment.h +1 -1
  28. data/ext/nokogiri/xml_dtd.c +1 -1
  29. data/ext/nokogiri/xml_dtd.h +1 -1
  30. data/ext/nokogiri/xml_entity_reference.c +13 -4
  31. data/ext/nokogiri/xml_entity_reference.h +1 -1
  32. data/ext/nokogiri/xml_io.h +1 -1
  33. data/ext/nokogiri/xml_namespace.c +69 -0
  34. data/ext/nokogiri/xml_namespace.h +12 -0
  35. data/ext/nokogiri/xml_node.c +232 -124
  36. data/ext/nokogiri/xml_node.h +3 -4
  37. data/ext/nokogiri/xml_node_set.c +206 -19
  38. data/ext/nokogiri/xml_node_set.h +1 -1
  39. data/ext/nokogiri/xml_processing_instruction.c +14 -4
  40. data/ext/nokogiri/xml_processing_instruction.h +1 -1
  41. data/ext/nokogiri/xml_reader.c +87 -7
  42. data/ext/nokogiri/xml_reader.h +1 -1
  43. data/ext/nokogiri/xml_relax_ng.c +106 -0
  44. data/ext/nokogiri/xml_relax_ng.h +9 -0
  45. data/ext/nokogiri/xml_sax_parser.c +122 -2
  46. data/ext/nokogiri/xml_sax_parser.h +1 -1
  47. data/ext/nokogiri/xml_sax_push_parser.c +1 -0
  48. data/ext/nokogiri/xml_sax_push_parser.h +1 -1
  49. data/ext/nokogiri/xml_schema.c +107 -0
  50. data/ext/nokogiri/xml_schema.h +9 -0
  51. data/ext/nokogiri/xml_syntax_error.h +1 -1
  52. data/ext/nokogiri/xml_text.c +10 -3
  53. data/ext/nokogiri/xml_text.h +1 -1
  54. data/ext/nokogiri/xml_xpath.h +1 -1
  55. data/ext/nokogiri/xml_xpath_context.h +1 -1
  56. data/ext/nokogiri/xslt_stylesheet.c +29 -16
  57. data/ext/nokogiri/xslt_stylesheet.h +1 -1
  58. data/lib/action-nokogiri.rb +7 -1
  59. data/lib/nokogiri.rb +21 -5
  60. data/lib/nokogiri/css/generated_parser.rb +49 -14
  61. data/lib/nokogiri/css/generated_tokenizer.rb +2 -2
  62. data/lib/nokogiri/css/node.rb +13 -3
  63. data/lib/nokogiri/css/parser.rb +8 -0
  64. data/lib/nokogiri/css/parser.y +7 -7
  65. data/lib/nokogiri/css/tokenizer.rb +2 -0
  66. data/lib/nokogiri/css/xpath_visitor.rb +10 -6
  67. data/lib/nokogiri/decorators/hpricot/node.rb +1 -1
  68. data/lib/nokogiri/decorators/hpricot/node_set.rb +2 -2
  69. data/lib/nokogiri/decorators/hpricot/xpath_visitor.rb +2 -0
  70. data/lib/nokogiri/decorators/slop.rb +3 -1
  71. data/lib/nokogiri/ffi/html/document.rb +37 -0
  72. data/lib/nokogiri/ffi/html/element_description.rb +85 -0
  73. data/lib/nokogiri/ffi/html/entity_lookup.rb +16 -0
  74. data/lib/nokogiri/ffi/html/sax/parser.rb +21 -0
  75. data/lib/nokogiri/ffi/io_callbacks.rb +32 -0
  76. data/lib/nokogiri/ffi/libxml.rb +314 -0
  77. data/lib/nokogiri/ffi/structs/common_node.rb +26 -0
  78. data/lib/nokogiri/ffi/structs/html_elem_desc.rb +24 -0
  79. data/lib/nokogiri/ffi/structs/html_entity_desc.rb +13 -0
  80. data/lib/nokogiri/ffi/structs/xml_alloc.rb +16 -0
  81. data/lib/nokogiri/ffi/structs/xml_attr.rb +19 -0
  82. data/lib/nokogiri/ffi/structs/xml_buffer.rb +16 -0
  83. data/lib/nokogiri/ffi/structs/xml_document.rb +108 -0
  84. data/lib/nokogiri/ffi/structs/xml_dtd.rb +26 -0
  85. data/lib/nokogiri/ffi/structs/xml_node.rb +28 -0
  86. data/lib/nokogiri/ffi/structs/xml_node_set.rb +53 -0
  87. data/lib/nokogiri/ffi/structs/xml_notation.rb +11 -0
  88. data/lib/nokogiri/ffi/structs/xml_ns.rb +15 -0
  89. data/lib/nokogiri/ffi/structs/xml_relax_ng.rb +14 -0
  90. data/lib/nokogiri/ffi/structs/xml_sax_handler.rb +51 -0
  91. data/lib/nokogiri/ffi/structs/xml_sax_push_parser_context.rb +14 -0
  92. data/lib/nokogiri/ffi/structs/xml_schema.rb +13 -0
  93. data/lib/nokogiri/ffi/structs/xml_syntax_error.rb +31 -0
  94. data/lib/nokogiri/ffi/structs/xml_text_reader.rb +12 -0
  95. data/lib/nokogiri/ffi/structs/xml_xpath_context.rb +37 -0
  96. data/lib/nokogiri/ffi/structs/xml_xpath_object.rb +35 -0
  97. data/lib/nokogiri/ffi/structs/xml_xpath_parser_context.rb +20 -0
  98. data/lib/nokogiri/ffi/structs/xslt_stylesheet.rb +13 -0
  99. data/lib/nokogiri/ffi/xml/attr.rb +41 -0
  100. data/lib/nokogiri/ffi/xml/cdata.rb +19 -0
  101. data/lib/nokogiri/ffi/xml/comment.rb +18 -0
  102. data/lib/nokogiri/ffi/xml/document.rb +107 -0
  103. data/lib/nokogiri/ffi/xml/document_fragment.rb +26 -0
  104. data/lib/nokogiri/ffi/xml/dtd.rb +42 -0
  105. data/lib/nokogiri/ffi/xml/entity_reference.rb +19 -0
  106. data/lib/nokogiri/ffi/xml/namespace.rb +38 -0
  107. data/lib/nokogiri/ffi/xml/node.rb +380 -0
  108. data/lib/nokogiri/ffi/xml/node_set.rb +130 -0
  109. data/lib/nokogiri/ffi/xml/processing_instruction.rb +20 -0
  110. data/lib/nokogiri/ffi/xml/reader.rb +217 -0
  111. data/lib/nokogiri/ffi/xml/relax_ng.rb +51 -0
  112. data/lib/nokogiri/ffi/xml/sax/parser.rb +148 -0
  113. data/lib/nokogiri/ffi/xml/sax/push_parser.rb +38 -0
  114. data/lib/nokogiri/ffi/xml/schema.rb +55 -0
  115. data/lib/nokogiri/ffi/xml/syntax_error.rb +76 -0
  116. data/lib/nokogiri/ffi/xml/text.rb +18 -0
  117. data/lib/nokogiri/ffi/xml/xpath.rb +19 -0
  118. data/lib/nokogiri/ffi/xml/xpath_context.rb +135 -0
  119. data/lib/nokogiri/ffi/xslt/stylesheet.rb +47 -0
  120. data/lib/nokogiri/hpricot.rb +14 -3
  121. data/lib/nokogiri/html.rb +11 -46
  122. data/lib/nokogiri/html/builder.rb +27 -1
  123. data/lib/nokogiri/html/document.rb +62 -6
  124. data/lib/nokogiri/html/document_fragment.rb +15 -0
  125. data/lib/nokogiri/html/element_description.rb +23 -0
  126. data/lib/nokogiri/html/entity_lookup.rb +2 -0
  127. data/lib/nokogiri/html/sax/parser.rb +27 -1
  128. data/lib/nokogiri/version.rb +26 -1
  129. data/lib/nokogiri/version_warning.rb +11 -0
  130. data/lib/nokogiri/xml.rb +25 -51
  131. data/lib/nokogiri/xml/builder.rb +166 -10
  132. data/lib/nokogiri/xml/cdata.rb +3 -1
  133. data/lib/nokogiri/xml/document.rb +39 -6
  134. data/lib/nokogiri/xml/document_fragment.rb +41 -1
  135. data/lib/nokogiri/xml/dtd.rb +3 -1
  136. data/lib/nokogiri/xml/entity_declaration.rb +3 -1
  137. data/lib/nokogiri/xml/fragment_handler.rb +24 -3
  138. data/lib/nokogiri/xml/namespace.rb +7 -0
  139. data/lib/nokogiri/xml/node.rb +314 -65
  140. data/lib/nokogiri/xml/node/save_options.rb +12 -2
  141. data/lib/nokogiri/xml/node_set.rb +58 -8
  142. data/lib/nokogiri/xml/parse_options.rb +80 -0
  143. data/lib/nokogiri/xml/processing_instruction.rb +2 -0
  144. data/lib/nokogiri/xml/reader.rb +42 -3
  145. data/lib/nokogiri/xml/relax_ng.rb +32 -0
  146. data/lib/nokogiri/xml/sax.rb +0 -7
  147. data/lib/nokogiri/xml/sax/document.rb +84 -0
  148. data/lib/nokogiri/xml/sax/parser.rb +38 -2
  149. data/lib/nokogiri/xml/sax/push_parser.rb +12 -0
  150. data/lib/nokogiri/xml/schema.rb +65 -0
  151. data/lib/nokogiri/xml/syntax_error.rb +11 -0
  152. data/lib/nokogiri/xml/xpath.rb +1 -1
  153. data/lib/nokogiri/xml/xpath_context.rb +2 -0
  154. data/lib/nokogiri/xslt.rb +21 -1
  155. data/lib/nokogiri/xslt/stylesheet.rb +19 -0
  156. data/lib/xsd/xmlparser/nokogiri.rb +12 -2
  157. data/tasks/test.rb +42 -19
  158. data/test/css/test_parser.rb +29 -0
  159. data/test/ffi/test_document.rb +35 -0
  160. data/test/files/address_book.rlx +12 -0
  161. data/test/files/address_book.xml +10 -0
  162. data/test/files/po.xml +32 -0
  163. data/test/files/po.xsd +66 -0
  164. data/test/helper.rb +38 -8
  165. data/test/html/sax/test_parser.rb +12 -0
  166. data/test/html/test_builder.rb +25 -2
  167. data/test/html/test_document.rb +91 -20
  168. data/test/html/test_document_fragment.rb +97 -0
  169. data/test/html/test_element_description.rb +95 -0
  170. data/test/html/test_node.rb +66 -3
  171. data/test/test_convert_xpath.rb +1 -1
  172. data/test/test_memory_leak.rb +57 -18
  173. data/test/test_nokogiri.rb +24 -2
  174. data/test/test_reader.rb +77 -0
  175. data/test/test_xslt_transforms.rb +120 -82
  176. data/test/xml/node/test_subclass.rb +44 -0
  177. data/test/xml/sax/test_parser.rb +9 -0
  178. data/test/xml/sax/test_push_parser.rb +24 -0
  179. data/test/xml/test_attr.rb +7 -0
  180. data/test/xml/test_builder.rb +48 -0
  181. data/test/xml/test_cdata.rb +19 -0
  182. data/test/xml/test_comment.rb +6 -0
  183. data/test/xml/test_document.rb +101 -2
  184. data/test/xml/test_document_fragment.rb +55 -3
  185. data/test/xml/test_entity_reference.rb +4 -0
  186. data/test/xml/test_namespace.rb +43 -0
  187. data/test/xml/test_node.rb +255 -8
  188. data/test/xml/test_node_attributes.rb +34 -0
  189. data/test/xml/test_node_encoding.rb +9 -2
  190. data/test/xml/test_node_set.rb +197 -1
  191. data/test/xml/test_parse_options.rb +52 -0
  192. data/test/xml/test_processing_instruction.rb +5 -0
  193. data/test/xml/test_relax_ng.rb +60 -0
  194. data/test/xml/test_schema.rb +65 -0
  195. data/test/xml/test_text.rb +5 -0
  196. data/test/xml/test_unparented_node.rb +3 -3
  197. metadata +128 -12
  198. data/lib/nokogiri/xml/comment.rb +0 -6
  199. data/lib/nokogiri/xml/element.rb +0 -6
  200. data/lib/nokogiri/xml/text.rb +0 -6
@@ -1,6 +1,32 @@
1
1
  module Nokogiri
2
2
  module HTML
3
- class Builder < XML::Builder
3
+ ###
4
+ # Nokogiri HTML builder is used for building HTML documents. It is very
5
+ # similar to the Nokogiri::XML::Builder. In fact, you should go read the
6
+ # documentation for Nokogiri::XML::Builder before reading this
7
+ # documentation.
8
+ #
9
+ # == Synopsis:
10
+ #
11
+ # Create an HTML document with a body that has an onload attribute, and a
12
+ # span tag with a class of "bold" that has content of "Hello world".
13
+ #
14
+ # builder = Nokogiri::HTML::Builder.new do |doc|
15
+ # doc.html {
16
+ # doc.body(:onload => 'some_func();') {
17
+ # doc.span.bold {
18
+ # doc.text "Hello world"
19
+ # }
20
+ # }
21
+ # }
22
+ # end
23
+ # puts builder.to_html
24
+ #
25
+ # The HTML builder inherits from the XML builder, so make sure to read the
26
+ # Nokogiri::XML::Builder documentation.
27
+ class Builder < Nokogiri::XML::Builder
28
+ ###
29
+ # Convert the builder to HTML
4
30
  def to_html
5
31
  @doc.to_html
6
32
  end
@@ -1,15 +1,71 @@
1
1
  module Nokogiri
2
2
  module HTML
3
- class Document < XML::Document
3
+ class Document < Nokogiri::XML::Document
4
+
5
+ def initialize *args
6
+ super
7
+ end
8
+
4
9
  ####
5
10
  # Serialize this Document with +encoding+ using +options+
6
- def serialize encoding = nil, options = XML::Node::SaveOptions::FORMAT |
7
- XML::Node::SaveOptions::AS_HTML |
8
- XML::Node::SaveOptions::NO_DECLARATION |
9
- XML::Node::SaveOptions::NO_EMPTY_TAGS
11
+ def serialize *args
12
+ if args.first && !args.first.is_a?(Hash)
13
+ $stderr.puts(<<-eowarn)
14
+ #{self.class}#serialize(encoding, save_opts) is deprecated and will be removed in
15
+ Nokogiri version 1.4.0 *or* after June 1 2009.
16
+ You called serialize from here:
17
+
18
+ #{caller.join("\n")}
10
19
 
11
- super(encoding, options)
20
+ Please change to #{self.class}#serialize(:encoding => enc, :save_with => opts)
21
+ eowarn
22
+ end
23
+
24
+ options = args.first.is_a?(Hash) ? args.shift : {
25
+ :encoding => args[0],
26
+ :save_with => args[1] || XML::Node::SaveOptions::FORMAT |
27
+ XML::Node::SaveOptions::AS_HTML |
28
+ XML::Node::SaveOptions::NO_DECLARATION |
29
+ XML::Node::SaveOptions::NO_EMPTY_TAGS
30
+ }
31
+ super(options)
32
+ end
33
+
34
+ ####
35
+ # Create a Nokogiri::XML::DocumentFragment from +tags+
36
+ def fragment tags
37
+ DocumentFragment.new(self, tags)
12
38
  end
39
+
40
+ class << self
41
+ ###
42
+ # Parse HTML. +thing+ may be a String, or any object that
43
+ # responds to _read_ and _close_ such as an IO, or StringIO.
44
+ # +url+ is resource where this document is located. +encoding+ is the
45
+ # encoding that should be used when processing the document. +options+
46
+ # is a number that sets options in the parser, such as
47
+ # Nokogiri::XML::PARSE_RECOVER. See the constants in
48
+ # Nokogiri::XML.
49
+ def parse string_or_io, url = nil, encoding = nil, options = 2145, &block
50
+
51
+ options = Nokogiri::XML::ParseOptions.new(options) if Fixnum === options
52
+ # Give the options to the user
53
+ yield options if block_given?
54
+
55
+ if string_or_io.respond_to?(:encoding)
56
+ encoding ||= string_or_io.encoding.name
57
+ end
58
+
59
+ if string_or_io.respond_to?(:read)
60
+ url ||= string_or_io.respond_to?(:path) ? string_or_io.path : nil
61
+ return self.read_io(string_or_io, url, encoding, options.to_i)
62
+ end
63
+
64
+ return self.new if(string_or_io.length == 0)
65
+ self.read_memory(string_or_io, url, encoding, options.to_i)
66
+ end
67
+ end
68
+
13
69
  end
14
70
  end
15
71
  end
@@ -0,0 +1,15 @@
1
+ module Nokogiri
2
+ module HTML
3
+ class DocumentFragment < Nokogiri::XML::DocumentFragment
4
+
5
+ class << self
6
+ ####
7
+ # Create a Nokogiri::XML::DocumentFragment from +tags+
8
+ def parse tags
9
+ HTML::DocumentFragment.new(HTML::Document.new, tags)
10
+ end
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,23 @@
1
+ module Nokogiri
2
+ module HTML
3
+ class ElementDescription
4
+ ###
5
+ # Is this element a block element?
6
+ def block?
7
+ !inline?
8
+ end
9
+
10
+ ###
11
+ # Convert this description to a string
12
+ def to_s
13
+ "#{name}: #{description}"
14
+ end
15
+
16
+ ###
17
+ # Inspection information
18
+ def inspect
19
+ "#<#{self.class.name}: #{name} #{description}>"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -3,6 +3,8 @@ module Nokogiri
3
3
  class EntityDescription < Struct.new(:value, :name, :description); end
4
4
 
5
5
  class EntityLookup
6
+ ###
7
+ # Look up entity with +name+
6
8
  def [] name
7
9
  (val = get(name)) && val.value
8
10
  end
@@ -1,16 +1,42 @@
1
1
  module Nokogiri
2
2
  module HTML
3
+ ###
4
+ # Nokogiri lets you write a SAX parser to process HTML but get HTML
5
+ # correction features.
6
+ #
7
+ # See Nokogiri::HTML::SAX::Parser for a basic example of using a
8
+ # SAX parser with HTML.
9
+ #
10
+ # For more information on SAX parsers, see Nokogiri::XML::SAX
3
11
  module SAX
4
- class Parser < XML::SAX::Parser
12
+ ###
13
+ # This class lets you perform SAX style parsing on HTML with HTML
14
+ # error correction.
15
+ #
16
+ # Here is a basic usage example:
17
+ #
18
+ # class MyDoc < Nokogiri::XML::SAX::Document
19
+ # def start_element name, attributes = []
20
+ # puts "found a #{name}"
21
+ # end
22
+ # end
23
+ #
24
+ # parser = Nokogiri::HTML::SAX::Parser.new(MyDoc.new)
25
+ # parser.parse(File.read(ARGV[0], 'rb'))
26
+ #
27
+ # For more information on SAX parsers, see Nokogiri::XML::SAX
28
+ class Parser < Nokogiri::XML::SAX::Parser
5
29
  ###
6
30
  # Parse html stored in +data+ using +encoding+
7
31
  def parse_memory data, encoding = 'UTF-8'
32
+ raise ArgumentError unless data
8
33
  native_parse_memory(data, encoding)
9
34
  end
10
35
 
11
36
  ###
12
37
  # Parse a file with +filename+
13
38
  def parse_file filename, encoding = 'UTF-8'
39
+ raise ArgumentError unless filename
14
40
  raise Errno::ENOENT unless File.exists?(filename)
15
41
  raise Errno::EISDIR if File.directory?(filename)
16
42
  native_parse_file filename, encoding
@@ -1,4 +1,29 @@
1
1
  module Nokogiri
2
2
  # The version of Nokogiri you are using
3
- VERSION = '1.2.3'
3
+ VERSION = '1.3.0'
4
+
5
+ # More complete version information about libxml
6
+ VERSION_INFO = {}
7
+ VERSION_INFO['warnings'] = []
8
+ VERSION_INFO['nokogiri'] = VERSION
9
+ if defined?(LIBXML_VERSION) && ! defined?(FFI)
10
+ VERSION_INFO['libxml'] = {}
11
+ VERSION_INFO['libxml']['binding'] = 'extension'
12
+ VERSION_INFO['libxml']['compiled'] = LIBXML_VERSION
13
+ VERSION_INFO['libxml']['loaded'] = LIBXML_PARSER_VERSION.scan(/^(.*)(..)(..)$/).first.collect{|j|j.to_i}.join(".")
14
+
15
+ if VERSION_INFO['libxml']['compiled'] != VERSION_INFO['libxml']['loaded']
16
+ warning = "Nokogiri was built against LibXML version #{VERSION_INFO['libxml']['compiled']}, but has dynamically loaded #{VERSION_INFO['libxml']['loaded']}"
17
+ VERSION_INFO['warnings'] << warning
18
+ warn "WARNING: #{warning}"
19
+ end
20
+ end
21
+
22
+ def self.ffi? # :nodoc:
23
+ Nokogiri::VERSION_INFO['libxml']['binding'] == 'ffi'
24
+ end
25
+
26
+ def self.is_2_6_16? # :nodoc:
27
+ Nokogiri::VERSION_INFO['libxml']['loaded'] <= '2.6.16'
28
+ end
4
29
  end
@@ -0,0 +1,11 @@
1
+ module Nokogiri
2
+ if self.is_2_6_16? && !defined?(I_KNOW_I_AM_USING_AN_OLD_AND_BUGGY_VERSION_OF_LIBXML2)
3
+ warn <<-eom
4
+ HI. You're using libxml2 version 2.6.16 which is over 4 years old and has
5
+ plenty of bugs. We suggest that for maximum HTML/XML parsing pleasure, you
6
+ upgrade your version of libxml2 and re-install nokogiri. If you like using
7
+ libxml2 version 2.6.16, but don't like this warning, please define the constant
8
+ I_KNOW_I_AM_USING_AN_OLD_AND_BUGGY_VERSION_OF_LIBXML2 before requring nokogiri.
9
+ eom
10
+ end
11
+ end
@@ -1,14 +1,14 @@
1
+ require 'nokogiri/xml/parse_options'
1
2
  require 'nokogiri/xml/sax'
2
3
  require 'nokogiri/xml/fragment_handler'
3
4
  require 'nokogiri/xml/node'
5
+ require 'nokogiri/xml/namespace'
4
6
  require 'nokogiri/xml/attr'
5
7
  require 'nokogiri/xml/dtd'
6
- require 'nokogiri/xml/text'
7
8
  require 'nokogiri/xml/cdata'
8
- require 'nokogiri/xml/processing_instruction'
9
- require 'nokogiri/xml/comment'
10
9
  require 'nokogiri/xml/document'
11
10
  require 'nokogiri/xml/document_fragment'
11
+ require 'nokogiri/xml/processing_instruction'
12
12
  require 'nokogiri/xml/node_set'
13
13
  require 'nokogiri/xml/syntax_error'
14
14
  require 'nokogiri/xml/xpath'
@@ -16,72 +16,46 @@ require 'nokogiri/xml/xpath_context'
16
16
  require 'nokogiri/xml/builder'
17
17
  require 'nokogiri/xml/reader'
18
18
  require 'nokogiri/xml/notation'
19
- require 'nokogiri/xml/element'
20
19
  require 'nokogiri/xml/entity_declaration'
20
+ require 'nokogiri/xml/schema'
21
+ require 'nokogiri/xml/relax_ng'
21
22
 
22
23
  module Nokogiri
23
24
  class << self
24
25
  ###
25
- # Parse an XML file. +thing+ may be a String, or any object that
26
- # responds to _read_ and _close_ such as an IO, or StringIO.
27
- # +url+ is resource where this document is located. +encoding+ is the
28
- # encoding that should be used when processing the document. +options+
29
- # is a number that sets options in the parser, such as
30
- # Nokogiri::XML::PARSE_RECOVER. See the constants in
31
- # Nokogiri::XML.
32
- def XML thing, url = nil, encoding = nil, options = 1
33
- Nokogiri::XML.parse(thing, url, encoding, options)
26
+ # Parse XML. Convenience method for Nokogiri::XML::Document.parse
27
+ def XML thing, url = nil, encoding = nil, options = 1, &block
28
+ Nokogiri::XML::Document.parse(thing, url, encoding, options, &block)
34
29
  end
35
30
  end
36
31
 
37
32
  module XML
38
- # Parser options
39
- PARSE_RECOVER = 1 << 0 # Recover from errors
40
- PARSE_NOENT = 1 << 1 # Substitute entities
41
- PARSE_DTDLOAD = 1 << 2 # Load external subsets
42
- PARSE_DTDATTR = 1 << 3 # Default DTD attributes
43
- PARSE_DTDVALID = 1 << 4 # validate with the DTD
44
- PARSE_NOERROR = 1 << 5 # suppress error reports
45
- PARSE_NOWARNING = 1 << 6 # suppress warning reports
46
- PARSE_PEDANTIC = 1 << 7 # pedantic error reporting
47
- PARSE_NOBLANKS = 1 << 8 # remove blank nodes
48
- PARSE_SAX1 = 1 << 9 # use the SAX1 interface internally
49
- PARSE_XINCLUDE = 1 << 10 # Implement XInclude substitition
50
- PARSE_NONET = 1 << 11 # Forbid network access
51
- PARSE_NODICT = 1 << 12 # Do not reuse the context dictionnary
52
- PARSE_NSCLEAN = 1 << 13 # remove redundant namespaces declarations
53
- PARSE_NOCDATA = 1 << 14 # merge CDATA as text nodes
54
- PARSE_NOXINCNODE = 1 << 15 # do not generate XINCLUDE START/END nodes
55
-
56
33
  class << self
57
- def Reader string, url = nil, encoding = nil, options = 0
58
- Reader.from_memory(string, url, encoding, options)
59
- end
60
-
61
34
  ###
62
- # Parse an XML document. See Nokogiri.XML.
63
- def parse string_or_io, url = nil, encoding = nil, options = 2159
64
- if string_or_io.respond_to?(:read)
65
- url ||= string_or_io.respond_to?(:path) ? string_or_io.path : nil
66
- return Document.read_io(string_or_io, url, encoding, options)
67
- end
35
+ # Parse an XML document using the Nokogiri::XML::Reader API. See
36
+ # Nokogiri::XML::Reader for mor information
37
+ def Reader string_or_io, url = nil, encoding = nil, options = 0
68
38
 
69
- # read_memory pukes on empty docs
70
- return Document.new if string_or_io.nil? or string_or_io.empty?
39
+ options = Nokogiri::XML::ParseOptions.new(options) if Fixnum === options
40
+ # Give the options to the user
41
+ yield options if block_given?
71
42
 
72
- Document.read_memory(string_or_io, url, encoding, options)
43
+ if string_or_io.respond_to? :read
44
+ return Reader.from_io(string_or_io, url, encoding, options.to_i)
45
+ end
46
+ Reader.from_memory(string_or_io, url, encoding, options.to_i)
73
47
  end
74
48
 
75
49
  ###
76
- # Sets whether or not entities should be substituted.
77
- def substitute_entities=(value = true)
78
- Document.substitute_entities = value
50
+ # Parse XML. Convenience method for Nokogiri::XML::Document.parse
51
+ def parse thing, url = nil, encoding = nil, options = 1, &block
52
+ Document.parse(thing, url, encoding, options, &block)
79
53
  end
80
54
 
81
- ###
82
- # Sets whether or not external subsets should be loaded
83
- def load_external_subsets=(value = true)
84
- Document.load_external_subsets = value
55
+ ####
56
+ # Parse a fragment from +string+ in to a NodeSet.
57
+ def fragment string
58
+ XML::DocumentFragment.parse(string)
85
59
  end
86
60
  end
87
61
  end
@@ -1,39 +1,180 @@
1
1
  module Nokogiri
2
2
  module XML
3
+ ###
4
+ # Nokogiri builder can be used for building XML and HTML documents.
5
+ #
6
+ # == Synopsis:
7
+ #
8
+ # builder = Nokogiri::XML::Builder.new do |xml|
9
+ # xml.root {
10
+ # xml.products {
11
+ # xml.widget {
12
+ # xml.id_ "10"
13
+ # xml.name "Awesome widget"
14
+ # }
15
+ # }
16
+ # }
17
+ # end
18
+ # puts builder.to_xml
19
+ #
20
+ # === Builder scope
21
+ #
22
+ # The builder allows two forms. When the builder is supplied with a block
23
+ # that has a parameter, the outside scope is maintained. This means you
24
+ # can access variables that are outside your builder. If you don't need
25
+ # outside scope, you can use the builder without the "xml" prefix like
26
+ # this:
27
+ #
28
+ # builder = Nokogiri::XML::Builder.new do
29
+ # root {
30
+ # products {
31
+ # widget {
32
+ # id_ "10"
33
+ # name "Awesome widget"
34
+ # }
35
+ # }
36
+ # }
37
+ # end
38
+ #
39
+ # == Special Tags
40
+ #
41
+ # The builder works by taking advantage of method_missing. Unfortunately
42
+ # some methods are defined in ruby that are difficult or dangerous to
43
+ # remove. You may want to create tags with the name "type", "class", and
44
+ # "id" for example. In that case, you can use an underscore to
45
+ # disambiguate your tag name from the method call.
46
+ #
47
+ # Here is an example of using the underscore to disambiguate tag names from
48
+ # ruby methods:
49
+ #
50
+ # @objects = [Object.new, Object.new, Object.new]
51
+ #
52
+ # builder = Nokogiri::XML::Builder.new do |xml|
53
+ # xml.root {
54
+ # xml.objects {
55
+ # @objects.each do |o|
56
+ # xml.object {
57
+ # xml.type_ o.type
58
+ # xml.class_ o.class.name
59
+ # xml.id_ o.id
60
+ # }
61
+ # end
62
+ # }
63
+ # }
64
+ # end
65
+ # puts builder.to_xml
66
+ #
67
+ # The underscore may be used with any tag name, and the last underscore
68
+ # will just be removed.
69
+ #
70
+ # == Tag Attributes
71
+ #
72
+ # Tag attributes may be supplied as method arguments. Here is our
73
+ # previous example, but using attributes rather than tags:
74
+ #
75
+ # @objects = [Object.new, Object.new, Object.new]
76
+ #
77
+ # builder = Nokogiri::XML::Builder.new do |xml|
78
+ # xml.root {
79
+ # xml.objects {
80
+ # @objects.each do |o|
81
+ # xml.object(:type => o.type, :class => o.class, :id => o.id)
82
+ # end
83
+ # }
84
+ # }
85
+ # end
86
+ # puts builder.to_xml
87
+ #
88
+ # === Tag Attribute Short Cuts
89
+ #
90
+ # A couple attribute short cuts are available when building tags. The
91
+ # short cuts are available by special method calls when building a tag.
92
+ #
93
+ # This example builds an "object" tag with the class attribute "classy"
94
+ # and the id of "thing":
95
+ #
96
+ # builder = Nokogiri::XML::Builder.new do |xml|
97
+ # xml.root {
98
+ # xml.objects {
99
+ # xml.object.classy.thing!
100
+ # }
101
+ # }
102
+ # end
103
+ # puts builder.to_xml
104
+ #
105
+ # All other options are still supported with this syntax, including
106
+ # blocks and extra tag attributes.
3
107
  class Builder
4
- attr_accessor :doc, :parent, :context
5
- def initialize &block
108
+ # The current Document object being built
109
+ attr_accessor :doc
110
+
111
+ # The parent of the current node being built
112
+ attr_accessor :parent
113
+
114
+ # A context object for use when the block has no arguments
115
+ attr_accessor :context
116
+
117
+ attr_accessor :arity # :nodoc:
118
+
119
+ ###
120
+ # Create a new Builder object. +options+ are sent to the top level
121
+ # Document that is being built.
122
+ #
123
+ # Building a document with a particular encoding for example:
124
+ #
125
+ # Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
126
+ # ...
127
+ # end
128
+ def initialize options = {}, &block
6
129
  namespace = self.class.name.split('::')
7
130
  namespace[-1] = 'Document'
8
- @doc = eval(namespace.join('::')).new
9
- @parent = @doc
10
- @context = nil
11
- if block_given?
131
+ @doc = eval(namespace.join('::')).new
132
+ @parent = @doc
133
+ @context = nil
134
+ @arity = nil
135
+
136
+ options.each do |k,v|
137
+ @doc.send(:"#{k}=", v)
138
+ end
139
+
140
+ return unless block_given?
141
+
142
+ @arity = block.arity
143
+ if @arity <= 0
12
144
  @context = eval('self', block.binding)
145
+ instance_eval(&block)
146
+ else
147
+ yield self
13
148
  end
14
- instance_eval(&block) if block_given?
149
+
15
150
  @parent = @doc
16
151
  end
17
152
 
153
+ ###
154
+ # Create a Text Node with content of +string+
18
155
  def text string
19
156
  node = Nokogiri::XML::Text.new(string.to_s, @doc)
20
157
  insert(node)
21
158
  end
22
159
 
160
+ ###
161
+ # Create a CDATA Node with content of +string+
23
162
  def cdata string
24
163
  node = Nokogiri::XML::CDATA.new(@doc, string.to_s)
25
164
  insert(node)
26
165
  end
27
166
 
167
+ ###
168
+ # Convert this Builder object to XML
28
169
  def to_xml
29
170
  @doc.to_xml
30
171
  end
31
172
 
32
- def method_missing method, *args, &block
173
+ def method_missing method, *args, &block # :nodoc:
33
174
  if @context && @context.respond_to?(method)
34
175
  @context.send(method, *args, &block)
35
176
  else
36
- node = Nokogiri::XML::Node.new(method.to_s, @doc) { |n|
177
+ node = Nokogiri::XML::Node.new(method.to_s.sub(/[_!]$/, ''), @doc) { |n|
37
178
  args.each do |arg|
38
179
  case arg
39
180
  when Hash
@@ -48,11 +189,18 @@ module Nokogiri
48
189
  end
49
190
 
50
191
  private
192
+ ###
193
+ # Insert +node+ as a child of the current Node
51
194
  def insert(node, &block)
52
195
  node.parent = @parent
53
196
  if block_given?
54
197
  @parent = node
55
- instance_eval(&block)
198
+ @arity ||= block.arity
199
+ if @arity <= 0
200
+ instance_eval(&block)
201
+ else
202
+ block.call(self)
203
+ end
56
204
  @parent = node.parent
57
205
  end
58
206
  NodeBuilder.new(node, self)
@@ -64,6 +212,14 @@ module Nokogiri
64
212
  @doc_builder = doc_builder
65
213
  end
66
214
 
215
+ def []= k, v
216
+ @node[k] = v
217
+ end
218
+
219
+ def [] k
220
+ @node[k]
221
+ end
222
+
67
223
  def method_missing(method, *args, &block)
68
224
  opts = args.last.is_a?(Hash) ? args.pop : {}
69
225
  case method.to_s