nokogiri 1.11.0.rc1-x86-linux
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.
- checksums.yaml +7 -0
- data/LICENSE-DEPENDENCIES.md +1614 -0
- data/LICENSE.md +9 -0
- data/README.md +200 -0
- data/bin/nokogiri +118 -0
- data/dependencies.yml +74 -0
- data/ext/nokogiri/depend +358 -0
- data/ext/nokogiri/extconf.rb +695 -0
- data/ext/nokogiri/html_document.c +170 -0
- data/ext/nokogiri/html_document.h +10 -0
- data/ext/nokogiri/html_element_description.c +279 -0
- data/ext/nokogiri/html_element_description.h +10 -0
- data/ext/nokogiri/html_entity_lookup.c +32 -0
- data/ext/nokogiri/html_entity_lookup.h +8 -0
- data/ext/nokogiri/html_sax_parser_context.c +116 -0
- data/ext/nokogiri/html_sax_parser_context.h +11 -0
- data/ext/nokogiri/html_sax_push_parser.c +87 -0
- data/ext/nokogiri/html_sax_push_parser.h +9 -0
- data/ext/nokogiri/nokogiri.c +147 -0
- data/ext/nokogiri/nokogiri.h +122 -0
- data/ext/nokogiri/xml_attr.c +103 -0
- data/ext/nokogiri/xml_attr.h +9 -0
- data/ext/nokogiri/xml_attribute_decl.c +70 -0
- data/ext/nokogiri/xml_attribute_decl.h +9 -0
- data/ext/nokogiri/xml_cdata.c +62 -0
- data/ext/nokogiri/xml_cdata.h +9 -0
- data/ext/nokogiri/xml_comment.c +69 -0
- data/ext/nokogiri/xml_comment.h +9 -0
- data/ext/nokogiri/xml_document.c +617 -0
- data/ext/nokogiri/xml_document.h +23 -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 +202 -0
- data/ext/nokogiri/xml_dtd.h +10 -0
- 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_encoding_handler.c +79 -0
- data/ext/nokogiri/xml_encoding_handler.h +8 -0
- data/ext/nokogiri/xml_entity_decl.c +110 -0
- data/ext/nokogiri/xml_entity_decl.h +10 -0
- data/ext/nokogiri/xml_entity_reference.c +52 -0
- data/ext/nokogiri/xml_entity_reference.h +9 -0
- data/ext/nokogiri/xml_io.c +61 -0
- data/ext/nokogiri/xml_io.h +11 -0
- data/ext/nokogiri/xml_libxml2_hacks.c +112 -0
- data/ext/nokogiri/xml_libxml2_hacks.h +12 -0
- data/ext/nokogiri/xml_namespace.c +111 -0
- data/ext/nokogiri/xml_namespace.h +14 -0
- data/ext/nokogiri/xml_node.c +1773 -0
- data/ext/nokogiri/xml_node.h +13 -0
- data/ext/nokogiri/xml_node_set.c +486 -0
- data/ext/nokogiri/xml_node_set.h +12 -0
- data/ext/nokogiri/xml_processing_instruction.c +56 -0
- data/ext/nokogiri/xml_processing_instruction.h +9 -0
- data/ext/nokogiri/xml_reader.c +668 -0
- data/ext/nokogiri/xml_reader.h +10 -0
- data/ext/nokogiri/xml_relax_ng.c +161 -0
- data/ext/nokogiri/xml_relax_ng.h +9 -0
- data/ext/nokogiri/xml_sax_parser.c +310 -0
- data/ext/nokogiri/xml_sax_parser.h +39 -0
- data/ext/nokogiri/xml_sax_parser_context.c +262 -0
- data/ext/nokogiri/xml_sax_parser_context.h +10 -0
- data/ext/nokogiri/xml_sax_push_parser.c +159 -0
- data/ext/nokogiri/xml_sax_push_parser.h +9 -0
- data/ext/nokogiri/xml_schema.c +205 -0
- data/ext/nokogiri/xml_schema.h +9 -0
- data/ext/nokogiri/xml_syntax_error.c +64 -0
- data/ext/nokogiri/xml_syntax_error.h +13 -0
- data/ext/nokogiri/xml_text.c +52 -0
- data/ext/nokogiri/xml_text.h +9 -0
- data/ext/nokogiri/xml_xpath_context.c +298 -0
- data/ext/nokogiri/xml_xpath_context.h +10 -0
- data/ext/nokogiri/xslt_stylesheet.c +266 -0
- data/ext/nokogiri/xslt_stylesheet.h +14 -0
- data/lib/nokogiri.rb +127 -0
- data/lib/nokogiri/2.4/nokogiri.so +0 -0
- data/lib/nokogiri/2.5/nokogiri.so +0 -0
- data/lib/nokogiri/2.6/nokogiri.so +0 -0
- data/lib/nokogiri/2.7/nokogiri.so +0 -0
- data/lib/nokogiri/css.rb +28 -0
- data/lib/nokogiri/css/node.rb +53 -0
- data/lib/nokogiri/css/parser.rb +751 -0
- data/lib/nokogiri/css/parser.y +272 -0
- data/lib/nokogiri/css/parser_extras.rb +92 -0
- data/lib/nokogiri/css/syntax_error.rb +8 -0
- data/lib/nokogiri/css/tokenizer.rb +154 -0
- data/lib/nokogiri/css/tokenizer.rex +55 -0
- data/lib/nokogiri/css/xpath_visitor.rb +232 -0
- data/lib/nokogiri/decorators/slop.rb +43 -0
- data/lib/nokogiri/html.rb +38 -0
- data/lib/nokogiri/html/builder.rb +36 -0
- data/lib/nokogiri/html/document.rb +336 -0
- data/lib/nokogiri/html/document_fragment.rb +50 -0
- data/lib/nokogiri/html/element_description.rb +24 -0
- data/lib/nokogiri/html/element_description_defaults.rb +672 -0
- data/lib/nokogiri/html/entity_lookup.rb +14 -0
- data/lib/nokogiri/html/sax/parser.rb +63 -0
- data/lib/nokogiri/html/sax/parser_context.rb +17 -0
- data/lib/nokogiri/html/sax/push_parser.rb +37 -0
- data/lib/nokogiri/jruby/dependencies.rb +20 -0
- data/lib/nokogiri/syntax_error.rb +5 -0
- data/lib/nokogiri/version.rb +149 -0
- data/lib/nokogiri/xml.rb +76 -0
- data/lib/nokogiri/xml/attr.rb +15 -0
- data/lib/nokogiri/xml/attribute_decl.rb +19 -0
- data/lib/nokogiri/xml/builder.rb +447 -0
- data/lib/nokogiri/xml/cdata.rb +12 -0
- data/lib/nokogiri/xml/character_data.rb +8 -0
- data/lib/nokogiri/xml/document.rb +280 -0
- data/lib/nokogiri/xml/document_fragment.rb +161 -0
- data/lib/nokogiri/xml/dtd.rb +33 -0
- data/lib/nokogiri/xml/element_content.rb +37 -0
- data/lib/nokogiri/xml/element_decl.rb +14 -0
- data/lib/nokogiri/xml/entity_decl.rb +20 -0
- data/lib/nokogiri/xml/entity_reference.rb +19 -0
- data/lib/nokogiri/xml/namespace.rb +14 -0
- data/lib/nokogiri/xml/node.rb +916 -0
- data/lib/nokogiri/xml/node/save_options.rb +62 -0
- data/lib/nokogiri/xml/node_set.rb +372 -0
- data/lib/nokogiri/xml/notation.rb +7 -0
- data/lib/nokogiri/xml/parse_options.rb +121 -0
- data/lib/nokogiri/xml/pp.rb +3 -0
- data/lib/nokogiri/xml/pp/character_data.rb +19 -0
- data/lib/nokogiri/xml/pp/node.rb +57 -0
- data/lib/nokogiri/xml/processing_instruction.rb +9 -0
- data/lib/nokogiri/xml/reader.rb +116 -0
- data/lib/nokogiri/xml/relax_ng.rb +33 -0
- data/lib/nokogiri/xml/sax.rb +5 -0
- data/lib/nokogiri/xml/sax/document.rb +172 -0
- data/lib/nokogiri/xml/sax/parser.rb +123 -0
- data/lib/nokogiri/xml/sax/parser_context.rb +17 -0
- data/lib/nokogiri/xml/sax/push_parser.rb +61 -0
- data/lib/nokogiri/xml/schema.rb +64 -0
- data/lib/nokogiri/xml/searchable.rb +231 -0
- data/lib/nokogiri/xml/syntax_error.rb +71 -0
- data/lib/nokogiri/xml/text.rb +10 -0
- data/lib/nokogiri/xml/xpath.rb +11 -0
- data/lib/nokogiri/xml/xpath/syntax_error.rb +12 -0
- data/lib/nokogiri/xml/xpath_context.rb +17 -0
- data/lib/nokogiri/xslt.rb +57 -0
- data/lib/nokogiri/xslt/stylesheet.rb +26 -0
- data/lib/xsd/xmlparser/nokogiri.rb +103 -0
- metadata +482 -0
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Nokogiri
|
3
|
+
module HTML
|
4
|
+
class EntityDescription < Struct.new(:value, :name, :description); end
|
5
|
+
|
6
|
+
class EntityLookup
|
7
|
+
###
|
8
|
+
# Look up entity with +name+
|
9
|
+
def [] name
|
10
|
+
(val = get(name)) && val.value
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Nokogiri
|
3
|
+
module HTML
|
4
|
+
###
|
5
|
+
# Nokogiri lets you write a SAX parser to process HTML but get HTML
|
6
|
+
# correction features.
|
7
|
+
#
|
8
|
+
# See Nokogiri::HTML::SAX::Parser for a basic example of using a
|
9
|
+
# SAX parser with HTML.
|
10
|
+
#
|
11
|
+
# For more information on SAX parsers, see Nokogiri::XML::SAX
|
12
|
+
module SAX
|
13
|
+
###
|
14
|
+
# This class lets you perform SAX style parsing on HTML with HTML
|
15
|
+
# error correction.
|
16
|
+
#
|
17
|
+
# Here is a basic usage example:
|
18
|
+
#
|
19
|
+
# class MyDoc < Nokogiri::XML::SAX::Document
|
20
|
+
# def start_element name, attributes = []
|
21
|
+
# puts "found a #{name}"
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# parser = Nokogiri::HTML::SAX::Parser.new(MyDoc.new)
|
26
|
+
# parser.parse(File.read(ARGV[0], mode: 'rb'))
|
27
|
+
#
|
28
|
+
# For more information on SAX parsers, see Nokogiri::XML::SAX
|
29
|
+
class Parser < Nokogiri::XML::SAX::Parser
|
30
|
+
###
|
31
|
+
# Parse html stored in +data+ using +encoding+
|
32
|
+
def parse_memory data, encoding = 'UTF-8'
|
33
|
+
raise ArgumentError unless data
|
34
|
+
return unless data.length > 0
|
35
|
+
ctx = ParserContext.memory(data, encoding)
|
36
|
+
yield ctx if block_given?
|
37
|
+
ctx.parse_with self
|
38
|
+
end
|
39
|
+
|
40
|
+
###
|
41
|
+
# Parse given +io+
|
42
|
+
def parse_io io, encoding = 'UTF-8'
|
43
|
+
check_encoding(encoding)
|
44
|
+
@encoding = encoding
|
45
|
+
ctx = ParserContext.io(io, ENCODINGS[encoding])
|
46
|
+
yield ctx if block_given?
|
47
|
+
ctx.parse_with self
|
48
|
+
end
|
49
|
+
|
50
|
+
###
|
51
|
+
# Parse a file with +filename+
|
52
|
+
def parse_file filename, encoding = 'UTF-8'
|
53
|
+
raise ArgumentError unless filename
|
54
|
+
raise Errno::ENOENT unless File.exist?(filename)
|
55
|
+
raise Errno::EISDIR if File.directory?(filename)
|
56
|
+
ctx = ParserContext.file(filename, encoding)
|
57
|
+
yield ctx if block_given?
|
58
|
+
ctx.parse_with self
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Nokogiri
|
3
|
+
module HTML
|
4
|
+
module SAX
|
5
|
+
###
|
6
|
+
# Context for HTML SAX parsers. This class is usually not instantiated
|
7
|
+
# by the user. Instead, you should be looking at
|
8
|
+
# Nokogiri::HTML::SAX::Parser
|
9
|
+
class ParserContext < Nokogiri::XML::SAX::ParserContext
|
10
|
+
def self.new thing, encoding = 'UTF-8'
|
11
|
+
[:read, :close].all? { |x| thing.respond_to?(x) } ? super :
|
12
|
+
memory(thing, encoding)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Nokogiri
|
3
|
+
module HTML
|
4
|
+
module SAX
|
5
|
+
class PushParser
|
6
|
+
|
7
|
+
# The Nokogiri::HTML::SAX::Document on which the PushParser will be
|
8
|
+
# operating
|
9
|
+
attr_accessor :document
|
10
|
+
|
11
|
+
def initialize(doc = HTML::SAX::Document.new, file_name = nil, encoding = 'UTF-8')
|
12
|
+
@document = doc
|
13
|
+
@encoding = encoding
|
14
|
+
@sax_parser = HTML::SAX::Parser.new(doc, @encoding)
|
15
|
+
|
16
|
+
## Create our push parser context
|
17
|
+
initialize_native(@sax_parser, file_name, encoding)
|
18
|
+
end
|
19
|
+
|
20
|
+
###
|
21
|
+
# Write a +chunk+ of HTML to the PushParser. Any callback methods
|
22
|
+
# that can be called will be called immediately.
|
23
|
+
def write chunk, last_chunk = false
|
24
|
+
native_write(chunk, last_chunk)
|
25
|
+
end
|
26
|
+
alias :<< :write
|
27
|
+
|
28
|
+
###
|
29
|
+
# Finish the parsing. This method is only necessary for
|
30
|
+
# Nokogiri::HTML::SAX::Document#end_document to be called.
|
31
|
+
def finish
|
32
|
+
write '', true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# The line below caused a problem on non-GAE rack environment.
|
3
|
+
# unless defined?(JRuby::Rack::VERSION) || defined?(AppEngine::ApiProxy)
|
4
|
+
#
|
5
|
+
# However, simply cutting defined?(JRuby::Rack::VERSION) off resulted in
|
6
|
+
# an unable-to-load-nokogiri problem. Thus, now, Nokogiri checks the presense
|
7
|
+
# of appengine-rack.jar in $LOAD_PATH. If Nokogiri is on GAE, Nokogiri
|
8
|
+
# should skip loading xml jars. This is because those are in WEB-INF/lib and
|
9
|
+
# already set in the classpath.
|
10
|
+
unless $LOAD_PATH.to_s.include?("appengine-rack")
|
11
|
+
require 'stringio'
|
12
|
+
require 'isorelax.jar'
|
13
|
+
require 'jing.jar'
|
14
|
+
require 'nekohtml.jar'
|
15
|
+
require 'nekodtd.jar'
|
16
|
+
require 'xercesImpl.jar'
|
17
|
+
require 'serializer.jar'
|
18
|
+
require 'xalan.jar'
|
19
|
+
require 'xml-apis.jar'
|
20
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Nokogiri
|
3
|
+
# The version of Nokogiri you are using
|
4
|
+
VERSION = "1.11.0.rc1"
|
5
|
+
|
6
|
+
class VersionInfo # :nodoc:
|
7
|
+
def jruby?
|
8
|
+
::JRUBY_VERSION if RUBY_PLATFORM == "java"
|
9
|
+
end
|
10
|
+
|
11
|
+
def engine
|
12
|
+
defined?(RUBY_ENGINE) ? RUBY_ENGINE : "mri"
|
13
|
+
end
|
14
|
+
|
15
|
+
def loaded_libxml_version
|
16
|
+
Gem::Version.new(LIBXML_LOADED_VERSION.
|
17
|
+
scan(/^(\d+)(\d\d)(\d\d)(?!\d)/).first.
|
18
|
+
collect(&:to_i).
|
19
|
+
join("."))
|
20
|
+
end
|
21
|
+
|
22
|
+
def compiled_libxml_version
|
23
|
+
Gem::Version.new LIBXML_COMPILED_VERSION
|
24
|
+
end
|
25
|
+
|
26
|
+
def loaded_libxslt_version
|
27
|
+
Gem::Version.new(LIBXSLT_LOADED_VERSION.
|
28
|
+
scan(/^(\d+)(\d\d)(\d\d)(?!\d)/).first.
|
29
|
+
collect(&:to_i).
|
30
|
+
join("."))
|
31
|
+
end
|
32
|
+
|
33
|
+
def compiled_libxslt_version
|
34
|
+
Gem::Version.new LIBXSLT_COMPILED_VERSION
|
35
|
+
end
|
36
|
+
|
37
|
+
def libxml2?
|
38
|
+
defined?(LIBXML_COMPILED_VERSION)
|
39
|
+
end
|
40
|
+
|
41
|
+
def libxml2_using_system?
|
42
|
+
!libxml2_using_packaged?
|
43
|
+
end
|
44
|
+
|
45
|
+
def libxml2_using_packaged?
|
46
|
+
NOKOGIRI_USE_PACKAGED_LIBRARIES
|
47
|
+
end
|
48
|
+
|
49
|
+
def warnings
|
50
|
+
warnings = []
|
51
|
+
|
52
|
+
if libxml2?
|
53
|
+
if compiled_libxml_version != loaded_libxml_version
|
54
|
+
warnings << "Nokogiri was built against libxml version #{compiled_libxml_version}, but has dynamically loaded #{loaded_libxml_version}"
|
55
|
+
end
|
56
|
+
|
57
|
+
if compiled_libxslt_version != loaded_libxslt_version
|
58
|
+
warnings << "Nokogiri was built against libxslt version #{compiled_libxslt_version}, but has dynamically loaded #{loaded_libxslt_version}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
warnings
|
63
|
+
end
|
64
|
+
|
65
|
+
def to_hash
|
66
|
+
{}.tap do |vi|
|
67
|
+
vi["warnings"] = []
|
68
|
+
vi["nokogiri"] = Nokogiri::VERSION
|
69
|
+
vi["ruby"] = {}.tap do |ruby|
|
70
|
+
ruby["version"] = ::RUBY_VERSION
|
71
|
+
ruby["platform"] = ::RUBY_PLATFORM
|
72
|
+
ruby["description"] = ::RUBY_DESCRIPTION
|
73
|
+
ruby["engine"] = engine
|
74
|
+
ruby["jruby"] = jruby? if jruby?
|
75
|
+
end
|
76
|
+
|
77
|
+
if libxml2?
|
78
|
+
vi["libxml"] = {}.tap do |libxml|
|
79
|
+
if libxml2_using_packaged?
|
80
|
+
libxml["source"] = "packaged"
|
81
|
+
libxml["patches"] = NOKOGIRI_LIBXML2_PATCHES
|
82
|
+
else
|
83
|
+
libxml["source"] = "system"
|
84
|
+
end
|
85
|
+
libxml["compiled"] = compiled_libxml_version.to_s
|
86
|
+
libxml["loaded"] = loaded_libxml_version.to_s
|
87
|
+
end
|
88
|
+
|
89
|
+
vi["libxslt"] = {}.tap do |libxslt|
|
90
|
+
if libxml2_using_packaged?
|
91
|
+
libxslt["source"] = "packaged"
|
92
|
+
libxslt["patches"] = NOKOGIRI_LIBXSLT_PATCHES
|
93
|
+
else
|
94
|
+
libxslt["source"] = "system"
|
95
|
+
end
|
96
|
+
libxslt["compiled"] = compiled_libxslt_version.to_s
|
97
|
+
libxslt["loaded"] = loaded_libxslt_version.to_s
|
98
|
+
end
|
99
|
+
|
100
|
+
vi["warnings"] = warnings
|
101
|
+
elsif jruby?
|
102
|
+
vi["xerces"] = Nokogiri::XERCES_VERSION
|
103
|
+
vi["nekohtml"] = Nokogiri::NEKO_VERSION
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def to_markdown
|
109
|
+
begin
|
110
|
+
require "psych"
|
111
|
+
rescue LoadError
|
112
|
+
end
|
113
|
+
require "yaml"
|
114
|
+
"# Nokogiri (#{Nokogiri::VERSION})\n" +
|
115
|
+
YAML.dump(to_hash).each_line.map { |line| " #{line}" }.join
|
116
|
+
end
|
117
|
+
|
118
|
+
# FIXME: maybe switch to singleton?
|
119
|
+
@@instance = new
|
120
|
+
@@instance.warnings.each do |warning|
|
121
|
+
warn "WARNING: #{warning}"
|
122
|
+
end
|
123
|
+
def self.instance; @@instance; end
|
124
|
+
end
|
125
|
+
|
126
|
+
def self.uses_libxml?(requirement = nil) # :nodoc:
|
127
|
+
return false unless VersionInfo.instance.libxml2?
|
128
|
+
return true unless requirement
|
129
|
+
return Gem::Requirement.new(requirement).satisfied_by?(VersionInfo.instance.loaded_libxml_version)
|
130
|
+
end
|
131
|
+
|
132
|
+
def self.jruby? # :nodoc:
|
133
|
+
VersionInfo.instance.jruby?
|
134
|
+
end
|
135
|
+
|
136
|
+
# Ensure constants used in this file are loaded
|
137
|
+
if Nokogiri.jruby?
|
138
|
+
require "nokogiri/jruby/dependencies"
|
139
|
+
end
|
140
|
+
begin
|
141
|
+
RUBY_VERSION =~ /(\d+\.\d+)/
|
142
|
+
require "nokogiri/#{$1}/nokogiri"
|
143
|
+
rescue LoadError
|
144
|
+
require "nokogiri/nokogiri"
|
145
|
+
end
|
146
|
+
|
147
|
+
# More complete version information about libxml
|
148
|
+
VERSION_INFO = VersionInfo.instance.to_hash
|
149
|
+
end
|
data/lib/nokogiri/xml.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'nokogiri/xml/pp'
|
3
|
+
require 'nokogiri/xml/parse_options'
|
4
|
+
require 'nokogiri/xml/sax'
|
5
|
+
require 'nokogiri/xml/searchable'
|
6
|
+
require 'nokogiri/xml/node'
|
7
|
+
require 'nokogiri/xml/attribute_decl'
|
8
|
+
require 'nokogiri/xml/element_decl'
|
9
|
+
require 'nokogiri/xml/element_content'
|
10
|
+
require 'nokogiri/xml/character_data'
|
11
|
+
require 'nokogiri/xml/namespace'
|
12
|
+
require 'nokogiri/xml/attr'
|
13
|
+
require 'nokogiri/xml/dtd'
|
14
|
+
require 'nokogiri/xml/cdata'
|
15
|
+
require 'nokogiri/xml/text'
|
16
|
+
require 'nokogiri/xml/document'
|
17
|
+
require 'nokogiri/xml/document_fragment'
|
18
|
+
require 'nokogiri/xml/processing_instruction'
|
19
|
+
require 'nokogiri/xml/node_set'
|
20
|
+
require 'nokogiri/xml/syntax_error'
|
21
|
+
require 'nokogiri/xml/xpath'
|
22
|
+
require 'nokogiri/xml/xpath_context'
|
23
|
+
require 'nokogiri/xml/builder'
|
24
|
+
require 'nokogiri/xml/reader'
|
25
|
+
require 'nokogiri/xml/notation'
|
26
|
+
require 'nokogiri/xml/entity_decl'
|
27
|
+
require 'nokogiri/xml/entity_reference'
|
28
|
+
require 'nokogiri/xml/schema'
|
29
|
+
require 'nokogiri/xml/relax_ng'
|
30
|
+
|
31
|
+
module Nokogiri
|
32
|
+
class << self
|
33
|
+
###
|
34
|
+
# Parse XML. Convenience method for Nokogiri::XML::Document.parse
|
35
|
+
def XML thing, url = nil, encoding = nil, options = XML::ParseOptions::DEFAULT_XML, &block
|
36
|
+
Nokogiri::XML::Document.parse(thing, url, encoding, options, &block)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
module XML
|
41
|
+
# Original C14N 1.0 spec canonicalization
|
42
|
+
XML_C14N_1_0 = 0
|
43
|
+
# Exclusive C14N 1.0 spec canonicalization
|
44
|
+
XML_C14N_EXCLUSIVE_1_0 = 1
|
45
|
+
# C14N 1.1 spec canonicalization
|
46
|
+
XML_C14N_1_1 = 2
|
47
|
+
class << self
|
48
|
+
###
|
49
|
+
# Parse an XML document using the Nokogiri::XML::Reader API. See
|
50
|
+
# Nokogiri::XML::Reader for mor information
|
51
|
+
def Reader string_or_io, url = nil, encoding = nil, options = ParseOptions::STRICT
|
52
|
+
|
53
|
+
options = Nokogiri::XML::ParseOptions.new(options) if Integer === options
|
54
|
+
# Give the options to the user
|
55
|
+
yield options if block_given?
|
56
|
+
|
57
|
+
if string_or_io.respond_to? :read
|
58
|
+
return Reader.from_io(string_or_io, url, encoding, options.to_i)
|
59
|
+
end
|
60
|
+
Reader.from_memory(string_or_io, url, encoding, options.to_i)
|
61
|
+
end
|
62
|
+
|
63
|
+
###
|
64
|
+
# Parse XML. Convenience method for Nokogiri::XML::Document.parse
|
65
|
+
def parse thing, url = nil, encoding = nil, options = ParseOptions::DEFAULT_XML, &block
|
66
|
+
Document.parse(thing, url, encoding, options, &block)
|
67
|
+
end
|
68
|
+
|
69
|
+
####
|
70
|
+
# Parse a fragment from +string+ in to a NodeSet.
|
71
|
+
def fragment string
|
72
|
+
XML::DocumentFragment.parse(string)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Nokogiri
|
3
|
+
module XML
|
4
|
+
###
|
5
|
+
# Represents an attribute declaration in a DTD
|
6
|
+
class AttributeDecl < Nokogiri::XML::Node
|
7
|
+
undef_method :attribute_nodes
|
8
|
+
undef_method :attributes
|
9
|
+
undef_method :content
|
10
|
+
undef_method :namespace
|
11
|
+
undef_method :namespace_definitions
|
12
|
+
undef_method :line if method_defined?(:line)
|
13
|
+
|
14
|
+
def inspect
|
15
|
+
"#<#{self.class.name}:#{sprintf("0x%x", object_id)} #{to_s.inspect}>"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,447 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Nokogiri
|
3
|
+
module XML
|
4
|
+
###
|
5
|
+
# Nokogiri builder can be used for building XML and HTML documents.
|
6
|
+
#
|
7
|
+
# == Synopsis:
|
8
|
+
#
|
9
|
+
# builder = Nokogiri::XML::Builder.new do |xml|
|
10
|
+
# xml.root {
|
11
|
+
# xml.products {
|
12
|
+
# xml.widget {
|
13
|
+
# xml.id_ "10"
|
14
|
+
# xml.name "Awesome widget"
|
15
|
+
# }
|
16
|
+
# }
|
17
|
+
# }
|
18
|
+
# end
|
19
|
+
# puts builder.to_xml
|
20
|
+
#
|
21
|
+
# Will output:
|
22
|
+
#
|
23
|
+
# <?xml version="1.0"?>
|
24
|
+
# <root>
|
25
|
+
# <products>
|
26
|
+
# <widget>
|
27
|
+
# <id>10</id>
|
28
|
+
# <name>Awesome widget</name>
|
29
|
+
# </widget>
|
30
|
+
# </products>
|
31
|
+
# </root>
|
32
|
+
#
|
33
|
+
#
|
34
|
+
# === Builder scope
|
35
|
+
#
|
36
|
+
# The builder allows two forms. When the builder is supplied with a block
|
37
|
+
# that has a parameter, the outside scope is maintained. This means you
|
38
|
+
# can access variables that are outside your builder. If you don't need
|
39
|
+
# outside scope, you can use the builder without the "xml" prefix like
|
40
|
+
# this:
|
41
|
+
#
|
42
|
+
# builder = Nokogiri::XML::Builder.new do
|
43
|
+
# root {
|
44
|
+
# products {
|
45
|
+
# widget {
|
46
|
+
# id_ "10"
|
47
|
+
# name "Awesome widget"
|
48
|
+
# }
|
49
|
+
# }
|
50
|
+
# }
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# == Special Tags
|
54
|
+
#
|
55
|
+
# The builder works by taking advantage of method_missing. Unfortunately
|
56
|
+
# some methods are defined in ruby that are difficult or dangerous to
|
57
|
+
# remove. You may want to create tags with the name "type", "class", and
|
58
|
+
# "id" for example. In that case, you can use an underscore to
|
59
|
+
# disambiguate your tag name from the method call.
|
60
|
+
#
|
61
|
+
# Here is an example of using the underscore to disambiguate tag names from
|
62
|
+
# ruby methods:
|
63
|
+
#
|
64
|
+
# @objects = [Object.new, Object.new, Object.new]
|
65
|
+
#
|
66
|
+
# builder = Nokogiri::XML::Builder.new do |xml|
|
67
|
+
# xml.root {
|
68
|
+
# xml.objects {
|
69
|
+
# @objects.each do |o|
|
70
|
+
# xml.object {
|
71
|
+
# xml.type_ o.type
|
72
|
+
# xml.class_ o.class.name
|
73
|
+
# xml.id_ o.id
|
74
|
+
# }
|
75
|
+
# end
|
76
|
+
# }
|
77
|
+
# }
|
78
|
+
# end
|
79
|
+
# puts builder.to_xml
|
80
|
+
#
|
81
|
+
# The underscore may be used with any tag name, and the last underscore
|
82
|
+
# will just be removed. This code will output the following XML:
|
83
|
+
#
|
84
|
+
# <?xml version="1.0"?>
|
85
|
+
# <root>
|
86
|
+
# <objects>
|
87
|
+
# <object>
|
88
|
+
# <type>Object</type>
|
89
|
+
# <class>Object</class>
|
90
|
+
# <id>48390</id>
|
91
|
+
# </object>
|
92
|
+
# <object>
|
93
|
+
# <type>Object</type>
|
94
|
+
# <class>Object</class>
|
95
|
+
# <id>48380</id>
|
96
|
+
# </object>
|
97
|
+
# <object>
|
98
|
+
# <type>Object</type>
|
99
|
+
# <class>Object</class>
|
100
|
+
# <id>48370</id>
|
101
|
+
# </object>
|
102
|
+
# </objects>
|
103
|
+
# </root>
|
104
|
+
#
|
105
|
+
# == Tag Attributes
|
106
|
+
#
|
107
|
+
# Tag attributes may be supplied as method arguments. Here is our
|
108
|
+
# previous example, but using attributes rather than tags:
|
109
|
+
#
|
110
|
+
# @objects = [Object.new, Object.new, Object.new]
|
111
|
+
#
|
112
|
+
# builder = Nokogiri::XML::Builder.new do |xml|
|
113
|
+
# xml.root {
|
114
|
+
# xml.objects {
|
115
|
+
# @objects.each do |o|
|
116
|
+
# xml.object(:type => o.type, :class => o.class, :id => o.id)
|
117
|
+
# end
|
118
|
+
# }
|
119
|
+
# }
|
120
|
+
# end
|
121
|
+
# puts builder.to_xml
|
122
|
+
#
|
123
|
+
# === Tag Attribute Short Cuts
|
124
|
+
#
|
125
|
+
# A couple attribute short cuts are available when building tags. The
|
126
|
+
# short cuts are available by special method calls when building a tag.
|
127
|
+
#
|
128
|
+
# This example builds an "object" tag with the class attribute "classy"
|
129
|
+
# and the id of "thing":
|
130
|
+
#
|
131
|
+
# builder = Nokogiri::XML::Builder.new do |xml|
|
132
|
+
# xml.root {
|
133
|
+
# xml.objects {
|
134
|
+
# xml.object.classy.thing!
|
135
|
+
# }
|
136
|
+
# }
|
137
|
+
# end
|
138
|
+
# puts builder.to_xml
|
139
|
+
#
|
140
|
+
# Which will output:
|
141
|
+
#
|
142
|
+
# <?xml version="1.0"?>
|
143
|
+
# <root>
|
144
|
+
# <objects>
|
145
|
+
# <object class="classy" id="thing"/>
|
146
|
+
# </objects>
|
147
|
+
# </root>
|
148
|
+
#
|
149
|
+
# All other options are still supported with this syntax, including
|
150
|
+
# blocks and extra tag attributes.
|
151
|
+
#
|
152
|
+
# == Namespaces
|
153
|
+
#
|
154
|
+
# Namespaces are added similarly to attributes. Nokogiri::XML::Builder
|
155
|
+
# assumes that when an attribute starts with "xmlns", it is meant to be
|
156
|
+
# a namespace:
|
157
|
+
#
|
158
|
+
# builder = Nokogiri::XML::Builder.new { |xml|
|
159
|
+
# xml.root('xmlns' => 'default', 'xmlns:foo' => 'bar') do
|
160
|
+
# xml.tenderlove
|
161
|
+
# end
|
162
|
+
# }
|
163
|
+
# puts builder.to_xml
|
164
|
+
#
|
165
|
+
# Will output XML like this:
|
166
|
+
#
|
167
|
+
# <?xml version="1.0"?>
|
168
|
+
# <root xmlns:foo="bar" xmlns="default">
|
169
|
+
# <tenderlove/>
|
170
|
+
# </root>
|
171
|
+
#
|
172
|
+
# === Referencing declared namespaces
|
173
|
+
#
|
174
|
+
# Tags that reference non-default namespaces (i.e. a tag "foo:bar") can be
|
175
|
+
# built by using the Nokogiri::XML::Builder#[] method.
|
176
|
+
#
|
177
|
+
# For example:
|
178
|
+
#
|
179
|
+
# builder = Nokogiri::XML::Builder.new do |xml|
|
180
|
+
# xml.root('xmlns:foo' => 'bar') {
|
181
|
+
# xml.objects {
|
182
|
+
# xml['foo'].object.classy.thing!
|
183
|
+
# }
|
184
|
+
# }
|
185
|
+
# end
|
186
|
+
# puts builder.to_xml
|
187
|
+
#
|
188
|
+
# Will output this XML:
|
189
|
+
#
|
190
|
+
# <?xml version="1.0"?>
|
191
|
+
# <root xmlns:foo="bar">
|
192
|
+
# <objects>
|
193
|
+
# <foo:object class="classy" id="thing"/>
|
194
|
+
# </objects>
|
195
|
+
# </root>
|
196
|
+
#
|
197
|
+
# Note the "foo:object" tag.
|
198
|
+
#
|
199
|
+
# == Document Types
|
200
|
+
#
|
201
|
+
# To create a document type (DTD), access use the Builder#doc method to get
|
202
|
+
# the current context document. Then call Node#create_internal_subset to
|
203
|
+
# create the DTD node.
|
204
|
+
#
|
205
|
+
# For example, this Ruby:
|
206
|
+
#
|
207
|
+
# builder = Nokogiri::XML::Builder.new do |xml|
|
208
|
+
# xml.doc.create_internal_subset(
|
209
|
+
# 'html',
|
210
|
+
# "-//W3C//DTD HTML 4.01 Transitional//EN",
|
211
|
+
# "http://www.w3.org/TR/html4/loose.dtd"
|
212
|
+
# )
|
213
|
+
# xml.root do
|
214
|
+
# xml.foo
|
215
|
+
# end
|
216
|
+
# end
|
217
|
+
#
|
218
|
+
# puts builder.to_xml
|
219
|
+
#
|
220
|
+
# Will output this xml:
|
221
|
+
#
|
222
|
+
# <?xml version="1.0"?>
|
223
|
+
# <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
224
|
+
# <root>
|
225
|
+
# <foo/>
|
226
|
+
# </root>
|
227
|
+
#
|
228
|
+
class Builder
|
229
|
+
# The current Document object being built
|
230
|
+
attr_accessor :doc
|
231
|
+
|
232
|
+
# The parent of the current node being built
|
233
|
+
attr_accessor :parent
|
234
|
+
|
235
|
+
# A context object for use when the block has no arguments
|
236
|
+
attr_accessor :context
|
237
|
+
|
238
|
+
attr_accessor :arity # :nodoc:
|
239
|
+
|
240
|
+
###
|
241
|
+
# Create a builder with an existing root object. This is for use when
|
242
|
+
# you have an existing document that you would like to augment with
|
243
|
+
# builder methods. The builder context created will start with the
|
244
|
+
# given +root+ node.
|
245
|
+
#
|
246
|
+
# For example:
|
247
|
+
#
|
248
|
+
# doc = Nokogiri::XML(open('somedoc.xml'))
|
249
|
+
# Nokogiri::XML::Builder.with(doc.at('some_tag')) do |xml|
|
250
|
+
# # ... Use normal builder methods here ...
|
251
|
+
# xml.awesome # add the "awesome" tag below "some_tag"
|
252
|
+
# end
|
253
|
+
#
|
254
|
+
def self.with(root, &block)
|
255
|
+
new({}, root, &block)
|
256
|
+
end
|
257
|
+
|
258
|
+
###
|
259
|
+
# Create a new Builder object. +options+ are sent to the top level
|
260
|
+
# Document that is being built.
|
261
|
+
#
|
262
|
+
# Building a document with a particular encoding for example:
|
263
|
+
#
|
264
|
+
# Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
|
265
|
+
# ...
|
266
|
+
# end
|
267
|
+
def initialize(options = {}, root = nil, &block)
|
268
|
+
if root
|
269
|
+
@doc = root.document
|
270
|
+
@parent = root
|
271
|
+
else
|
272
|
+
klassname = "::" + (self.class.name.split("::")[0..-2] + ["Document"]).join("::")
|
273
|
+
klass = begin
|
274
|
+
Object.const_get(klassname)
|
275
|
+
rescue NameError
|
276
|
+
Nokogiri::XML::Document
|
277
|
+
end
|
278
|
+
@parent = @doc = klass.new
|
279
|
+
end
|
280
|
+
|
281
|
+
@context = nil
|
282
|
+
@arity = nil
|
283
|
+
@ns = nil
|
284
|
+
|
285
|
+
options.each do |k, v|
|
286
|
+
@doc.send(:"#{k}=", v)
|
287
|
+
end
|
288
|
+
|
289
|
+
return unless block_given?
|
290
|
+
|
291
|
+
@arity = block.arity
|
292
|
+
if @arity <= 0
|
293
|
+
@context = eval("self", block.binding)
|
294
|
+
instance_eval(&block)
|
295
|
+
else
|
296
|
+
yield self
|
297
|
+
end
|
298
|
+
|
299
|
+
@parent = @doc
|
300
|
+
end
|
301
|
+
|
302
|
+
###
|
303
|
+
# Create a Text Node with content of +string+
|
304
|
+
def text(string)
|
305
|
+
insert @doc.create_text_node(string)
|
306
|
+
end
|
307
|
+
|
308
|
+
###
|
309
|
+
# Create a CDATA Node with content of +string+
|
310
|
+
def cdata(string)
|
311
|
+
insert doc.create_cdata(string)
|
312
|
+
end
|
313
|
+
|
314
|
+
###
|
315
|
+
# Create a Comment Node with content of +string+
|
316
|
+
def comment(string)
|
317
|
+
insert doc.create_comment(string)
|
318
|
+
end
|
319
|
+
|
320
|
+
###
|
321
|
+
# Build a tag that is associated with namespace +ns+. Raises an
|
322
|
+
# ArgumentError if +ns+ has not been defined higher in the tree.
|
323
|
+
def [](ns)
|
324
|
+
if @parent != @doc
|
325
|
+
@ns = @parent.namespace_definitions.find { |x| x.prefix == ns.to_s }
|
326
|
+
end
|
327
|
+
return self if @ns
|
328
|
+
|
329
|
+
@parent.ancestors.each do |a|
|
330
|
+
next if a == doc
|
331
|
+
@ns = a.namespace_definitions.find { |x| x.prefix == ns.to_s }
|
332
|
+
return self if @ns
|
333
|
+
end
|
334
|
+
|
335
|
+
@ns = { :pending => ns.to_s }
|
336
|
+
return self
|
337
|
+
end
|
338
|
+
|
339
|
+
###
|
340
|
+
# Convert this Builder object to XML
|
341
|
+
def to_xml(*args)
|
342
|
+
if Nokogiri.jruby?
|
343
|
+
options = args.first.is_a?(Hash) ? args.shift : {}
|
344
|
+
if !options[:save_with]
|
345
|
+
options[:save_with] = Node::SaveOptions::AS_BUILDER
|
346
|
+
end
|
347
|
+
args.insert(0, options)
|
348
|
+
end
|
349
|
+
@doc.to_xml(*args)
|
350
|
+
end
|
351
|
+
|
352
|
+
###
|
353
|
+
# Append the given raw XML +string+ to the document
|
354
|
+
def <<(string)
|
355
|
+
@doc.fragment(string).children.each { |x| insert(x) }
|
356
|
+
end
|
357
|
+
|
358
|
+
def method_missing(method, *args, &block) # :nodoc:
|
359
|
+
if @context && @context.respond_to?(method)
|
360
|
+
@context.send(method, *args, &block)
|
361
|
+
else
|
362
|
+
node = @doc.create_element(method.to_s.sub(/[_!]$/, ""), *args) { |n|
|
363
|
+
# Set up the namespace
|
364
|
+
if @ns.is_a? Nokogiri::XML::Namespace
|
365
|
+
n.namespace = @ns
|
366
|
+
@ns = nil
|
367
|
+
end
|
368
|
+
}
|
369
|
+
|
370
|
+
if @ns.is_a? Hash
|
371
|
+
node.namespace = node.namespace_definitions.find { |x| x.prefix == @ns[:pending] }
|
372
|
+
if node.namespace.nil?
|
373
|
+
raise ArgumentError, "Namespace #{@ns[:pending]} has not been defined"
|
374
|
+
end
|
375
|
+
@ns = nil
|
376
|
+
end
|
377
|
+
|
378
|
+
insert(node, &block)
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
private
|
383
|
+
|
384
|
+
###
|
385
|
+
# Insert +node+ as a child of the current Node
|
386
|
+
def insert(node, &block)
|
387
|
+
node = @parent.add_child(node)
|
388
|
+
if block_given?
|
389
|
+
old_parent = @parent
|
390
|
+
@parent = node
|
391
|
+
@arity ||= block.arity
|
392
|
+
if @arity <= 0
|
393
|
+
instance_eval(&block)
|
394
|
+
else
|
395
|
+
block.call(self)
|
396
|
+
end
|
397
|
+
@parent = old_parent
|
398
|
+
end
|
399
|
+
NodeBuilder.new(node, self)
|
400
|
+
end
|
401
|
+
|
402
|
+
class NodeBuilder # :nodoc:
|
403
|
+
def initialize(node, doc_builder)
|
404
|
+
@node = node
|
405
|
+
@doc_builder = doc_builder
|
406
|
+
end
|
407
|
+
|
408
|
+
def []=(k, v)
|
409
|
+
@node[k] = v
|
410
|
+
end
|
411
|
+
|
412
|
+
def [](k)
|
413
|
+
@node[k]
|
414
|
+
end
|
415
|
+
|
416
|
+
def method_missing(method, *args, &block)
|
417
|
+
opts = args.last.is_a?(Hash) ? args.pop : {}
|
418
|
+
case method.to_s
|
419
|
+
when /^(.*)!$/
|
420
|
+
@node["id"] = $1
|
421
|
+
@node.content = args.first if args.first
|
422
|
+
when /^(.*)=/
|
423
|
+
@node[$1] = args.first
|
424
|
+
else
|
425
|
+
@node["class"] =
|
426
|
+
((@node["class"] || "").split(/\s/) + [method.to_s]).join(" ")
|
427
|
+
@node.content = args.first if args.first
|
428
|
+
end
|
429
|
+
|
430
|
+
# Assign any extra options
|
431
|
+
opts.each do |k, v|
|
432
|
+
@node[k.to_s] = ((@node[k.to_s] || "").split(/\s/) + [v]).join(" ")
|
433
|
+
end
|
434
|
+
|
435
|
+
if block_given?
|
436
|
+
old_parent = @doc_builder.parent
|
437
|
+
@doc_builder.parent = @node
|
438
|
+
value = @doc_builder.instance_eval(&block)
|
439
|
+
@doc_builder.parent = old_parent
|
440
|
+
return value
|
441
|
+
end
|
442
|
+
self
|
443
|
+
end
|
444
|
+
end
|
445
|
+
end
|
446
|
+
end
|
447
|
+
end
|