nokogiri 1.16.3 → 1.18.1
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 +4 -4
- data/Gemfile +14 -22
- data/LICENSE-DEPENDENCIES.md +6 -6
- data/README.md +8 -5
- data/dependencies.yml +9 -9
- data/ext/nokogiri/extconf.rb +188 -142
- data/ext/nokogiri/gumbo.c +69 -53
- data/ext/nokogiri/html4_document.c +10 -4
- data/ext/nokogiri/html4_element_description.c +18 -18
- data/ext/nokogiri/html4_sax_parser.c +40 -0
- data/ext/nokogiri/html4_sax_parser_context.c +48 -58
- data/ext/nokogiri/html4_sax_push_parser.c +25 -24
- data/ext/nokogiri/libxml2_polyfill.c +114 -0
- data/ext/nokogiri/nokogiri.c +9 -2
- data/ext/nokogiri/nokogiri.h +18 -33
- data/ext/nokogiri/xml_attr.c +1 -1
- data/ext/nokogiri/xml_cdata.c +2 -10
- data/ext/nokogiri/xml_comment.c +3 -8
- data/ext/nokogiri/xml_document.c +163 -156
- data/ext/nokogiri/xml_document_fragment.c +10 -25
- data/ext/nokogiri/xml_dtd.c +1 -1
- data/ext/nokogiri/xml_element_content.c +9 -9
- data/ext/nokogiri/xml_encoding_handler.c +4 -4
- data/ext/nokogiri/xml_namespace.c +6 -6
- data/ext/nokogiri/xml_node.c +141 -104
- data/ext/nokogiri/xml_node_set.c +46 -44
- data/ext/nokogiri/xml_reader.c +54 -58
- data/ext/nokogiri/xml_relax_ng.c +35 -56
- data/ext/nokogiri/xml_sax_parser.c +156 -88
- data/ext/nokogiri/xml_sax_parser_context.c +219 -131
- data/ext/nokogiri/xml_sax_push_parser.c +68 -49
- data/ext/nokogiri/xml_schema.c +50 -85
- data/ext/nokogiri/xml_syntax_error.c +19 -11
- data/ext/nokogiri/xml_text.c +2 -4
- data/ext/nokogiri/xml_xpath_context.c +103 -100
- data/ext/nokogiri/xslt_stylesheet.c +8 -8
- data/gumbo-parser/src/ascii.c +2 -2
- data/gumbo-parser/src/error.c +76 -48
- data/gumbo-parser/src/error.h +5 -1
- data/gumbo-parser/src/nokogiri_gumbo.h +11 -2
- data/gumbo-parser/src/parser.c +63 -25
- data/gumbo-parser/src/tokenizer.c +6 -6
- data/lib/nokogiri/class_resolver.rb +1 -1
- data/lib/nokogiri/css/node.rb +6 -2
- data/lib/nokogiri/css/parser.rb +6 -4
- data/lib/nokogiri/css/parser.y +2 -2
- data/lib/nokogiri/css/parser_extras.rb +6 -66
- data/lib/nokogiri/css/selector_cache.rb +38 -0
- data/lib/nokogiri/css/tokenizer.rb +4 -4
- data/lib/nokogiri/css/tokenizer.rex +9 -8
- data/lib/nokogiri/css/xpath_visitor.rb +42 -6
- data/lib/nokogiri/css.rb +86 -20
- data/lib/nokogiri/decorators/slop.rb +3 -5
- data/lib/nokogiri/encoding_handler.rb +2 -2
- data/lib/nokogiri/html4/document.rb +44 -23
- data/lib/nokogiri/html4/document_fragment.rb +124 -12
- data/lib/nokogiri/html4/encoding_reader.rb +1 -1
- data/lib/nokogiri/html4/sax/parser.rb +23 -38
- data/lib/nokogiri/html4/sax/parser_context.rb +4 -9
- data/lib/nokogiri/html4.rb +9 -14
- data/lib/nokogiri/html5/builder.rb +40 -0
- data/lib/nokogiri/html5/document.rb +61 -30
- data/lib/nokogiri/html5/document_fragment.rb +130 -20
- data/lib/nokogiri/html5/node.rb +4 -4
- data/lib/nokogiri/html5.rb +114 -72
- data/lib/nokogiri/version/constant.rb +1 -1
- data/lib/nokogiri/xml/builder.rb +8 -1
- data/lib/nokogiri/xml/document.rb +70 -26
- data/lib/nokogiri/xml/document_fragment.rb +84 -13
- data/lib/nokogiri/xml/node.rb +82 -11
- data/lib/nokogiri/xml/node_set.rb +9 -7
- data/lib/nokogiri/xml/parse_options.rb +1 -1
- data/lib/nokogiri/xml/pp/node.rb +6 -1
- data/lib/nokogiri/xml/reader.rb +46 -13
- data/lib/nokogiri/xml/relax_ng.rb +57 -20
- data/lib/nokogiri/xml/sax/document.rb +174 -83
- data/lib/nokogiri/xml/sax/parser.rb +115 -41
- data/lib/nokogiri/xml/sax/parser_context.rb +116 -8
- data/lib/nokogiri/xml/sax/push_parser.rb +3 -0
- data/lib/nokogiri/xml/sax.rb +48 -0
- data/lib/nokogiri/xml/schema.rb +112 -45
- data/lib/nokogiri/xml/searchable.rb +38 -42
- data/lib/nokogiri/xml/syntax_error.rb +22 -0
- data/lib/nokogiri/xml/xpath_context.rb +14 -3
- data/lib/nokogiri/xml.rb +13 -24
- data/lib/nokogiri/xslt.rb +3 -9
- data/lib/xsd/xmlparser/nokogiri.rb +3 -4
- data/patches/libxml2/0019-xpath-Use-separate-static-hash-table-for-standard-fu.patch +244 -0
- data/ports/archives/libxml2-2.13.5.tar.xz +0 -0
- data/ports/archives/libxslt-1.1.42.tar.xz +0 -0
- metadata +13 -14
- data/ext/nokogiri/libxml2_backwards_compat.c +0 -121
- data/patches/libxml2/0003-libxml2.la-is-in-top_builddir.patch +0 -25
- data/ports/archives/libxml2-2.12.6.tar.xz +0 -0
- data/ports/archives/libxslt-1.1.39.tar.xz +0 -0
@@ -4,15 +4,123 @@ module Nokogiri
|
|
4
4
|
module XML
|
5
5
|
module SAX
|
6
6
|
###
|
7
|
-
# Context
|
8
|
-
#
|
9
|
-
# Nokogiri::XML::SAX::Parser
|
7
|
+
# Context object to invoke the XML SAX parser on the SAX::Document handler.
|
8
|
+
#
|
9
|
+
# 💡 This class is usually not instantiated by the user. Use Nokogiri::XML::SAX::Parser
|
10
|
+
# instead.
|
10
11
|
class ParserContext
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
class << self
|
13
|
+
###
|
14
|
+
# :call-seq:
|
15
|
+
# new(input)
|
16
|
+
# new(input, encoding)
|
17
|
+
#
|
18
|
+
# Create a parser context for an IO or a String. This is a shorthand method for
|
19
|
+
# ParserContext.io and ParserContext.memory.
|
20
|
+
#
|
21
|
+
# [Parameters]
|
22
|
+
# - +input+ (IO, String) A String or a readable IO object
|
23
|
+
# - +encoding+ (optional) (Encoding) The +Encoding+ to use, or the name of an
|
24
|
+
# encoding to use (default +nil+, encoding will be autodetected)
|
25
|
+
#
|
26
|
+
# If +input+ quacks like a readable IO object, this method forwards to ParserContext.io,
|
27
|
+
# otherwise it forwards to ParserContext.memory.
|
28
|
+
#
|
29
|
+
# [Returns] Nokogiri::XML::SAX::ParserContext
|
30
|
+
#
|
31
|
+
def new(input, encoding = nil)
|
32
|
+
if [:read, :close].all? { |x| input.respond_to?(x) }
|
33
|
+
io(input, encoding)
|
34
|
+
else
|
35
|
+
memory(input, encoding)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
###
|
40
|
+
# :call-seq:
|
41
|
+
# io(input)
|
42
|
+
# io(input, encoding)
|
43
|
+
#
|
44
|
+
# Create a parser context for an +input+ IO which will assume +encoding+
|
45
|
+
#
|
46
|
+
# [Parameters]
|
47
|
+
# - +io+ (IO) The readable IO object from which to read input
|
48
|
+
# - +encoding+ (optional) (Encoding) The +Encoding+ to use, or the name of an
|
49
|
+
# encoding to use (default +nil+, encoding will be autodetected)
|
50
|
+
#
|
51
|
+
# [Returns] Nokogiri::XML::SAX::ParserContext
|
52
|
+
#
|
53
|
+
# 💡 Calling this method directly is discouraged. Use Nokogiri::XML::SAX::Parser parse
|
54
|
+
# methods which are more convenient for most use cases.
|
55
|
+
#
|
56
|
+
def io(input, encoding = nil)
|
57
|
+
native_io(input, resolve_encoding(encoding))
|
58
|
+
end
|
59
|
+
|
60
|
+
###
|
61
|
+
# :call-seq:
|
62
|
+
# memory(input)
|
63
|
+
# memory(input, encoding)
|
64
|
+
#
|
65
|
+
# Create a parser context for the +input+ String.
|
66
|
+
#
|
67
|
+
# [Parameters]
|
68
|
+
# - +input+ (String) The input string to be parsed.
|
69
|
+
# - +encoding+ (optional) (Encoding, String) The +Encoding+ to use, or the name of an encoding to
|
70
|
+
# use (default +nil+, encoding will be autodetected)
|
71
|
+
#
|
72
|
+
# [Returns] Nokogiri::XML::SAX::ParserContext
|
73
|
+
#
|
74
|
+
# 💡 Calling this method directly is discouraged. Use Nokogiri::XML::SAX::Parser parse methods
|
75
|
+
# which are more convenient for most use cases.
|
76
|
+
#
|
77
|
+
def memory(input, encoding = nil)
|
78
|
+
native_memory(input, resolve_encoding(encoding))
|
79
|
+
end
|
80
|
+
|
81
|
+
###
|
82
|
+
# :call-seq:
|
83
|
+
# file(path)
|
84
|
+
# file(path, encoding)
|
85
|
+
#
|
86
|
+
# Create a parser context for the file at +path+.
|
87
|
+
#
|
88
|
+
# [Parameters]
|
89
|
+
# - +path+ (String) The path to the input file
|
90
|
+
# - +encoding+ (optional) (Encoding, String) The +Encoding+ to use, or the name of an encoding to
|
91
|
+
# use (default +nil+, encoding will be autodetected)
|
92
|
+
#
|
93
|
+
# [Returns] Nokogiri::XML::SAX::ParserContext
|
94
|
+
#
|
95
|
+
# 💡 Calling this method directly is discouraged. Use Nokogiri::XML::SAX::Parser.parse_file which
|
96
|
+
# is more convenient for most use cases.
|
97
|
+
def file(input, encoding = nil)
|
98
|
+
native_file(input, resolve_encoding(encoding))
|
99
|
+
end
|
100
|
+
|
101
|
+
private def resolve_encoding(encoding)
|
102
|
+
case encoding
|
103
|
+
when Encoding
|
104
|
+
encoding
|
105
|
+
|
106
|
+
when nil
|
107
|
+
nil # totally fine, parser will guess encoding
|
108
|
+
|
109
|
+
when Integer
|
110
|
+
warn("Passing an integer to Nokogiri::XML::SAX::ParserContext.io is deprecated. Use an Encoding object instead. This will become an error in a future release.", uplevel: 2, category: :deprecated)
|
111
|
+
|
112
|
+
return nil if encoding == Parser::ENCODINGS["NONE"]
|
113
|
+
|
114
|
+
encoding = Parser::REVERSE_ENCODINGS[encoding]
|
115
|
+
raise ArgumentError, "Invalid libxml2 encoding id #{encoding}" if encoding.nil?
|
116
|
+
Encoding.find(encoding)
|
117
|
+
|
118
|
+
when String
|
119
|
+
Encoding.find(encoding)
|
120
|
+
|
121
|
+
else
|
122
|
+
raise ArgumentError, "Cannot resolve #{encoding.inspect} to an Encoding"
|
123
|
+
end
|
16
124
|
end
|
17
125
|
end
|
18
126
|
end
|
@@ -52,6 +52,9 @@ module Nokogiri
|
|
52
52
|
###
|
53
53
|
# Finish the parsing. This method is only necessary for
|
54
54
|
# Nokogiri::XML::SAX::Document#end_document to be called.
|
55
|
+
#
|
56
|
+
# ⚠ Note that empty documents are treated as an error when using the libxml2-based
|
57
|
+
# implementation (CRuby), but are fine when using the Xerces-based implementation (JRuby).
|
55
58
|
def finish
|
56
59
|
write("", true)
|
57
60
|
end
|
data/lib/nokogiri/xml/sax.rb
CHANGED
@@ -1,5 +1,53 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
module Nokogiri
|
4
|
+
module XML
|
5
|
+
###
|
6
|
+
# SAX Parsers are event-driven parsers.
|
7
|
+
#
|
8
|
+
# Two SAX parsers for XML are available, a parser that reads from a string or IO object as it
|
9
|
+
# feels necessary, and a parser that you explicitly feed XML in chunks. If you want to let
|
10
|
+
# Nokogiri deal with reading your XML, use the Nokogiri::XML::SAX::Parser. If you want to have
|
11
|
+
# fine grain control over the XML input, use the Nokogiri::XML::SAX::PushParser.
|
12
|
+
#
|
13
|
+
# If you want to do SAX style parsing of HTML, check out Nokogiri::HTML4::SAX.
|
14
|
+
#
|
15
|
+
# The basic way a SAX style parser works is by creating a parser, telling the parser about the
|
16
|
+
# events we're interested in, then giving the parser some XML to process. The parser will notify
|
17
|
+
# you when it encounters events you said you would like to know about.
|
18
|
+
#
|
19
|
+
# To register for events, subclass Nokogiri::XML::SAX::Document and implement the methods for
|
20
|
+
# which you would like notification.
|
21
|
+
#
|
22
|
+
# For example, if I want to be notified when a document ends, and when an element starts, I
|
23
|
+
# would write a class like this:
|
24
|
+
#
|
25
|
+
# class MyHandler < Nokogiri::XML::SAX::Document
|
26
|
+
# def end_document
|
27
|
+
# puts "the document has ended"
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# def start_element name, attributes = []
|
31
|
+
# puts "#{name} started"
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# Then I would instantiate a SAX parser with this document, and feed the parser some XML
|
36
|
+
#
|
37
|
+
# # Create a new parser
|
38
|
+
# parser = Nokogiri::XML::SAX::Parser.new(MyHandler.new)
|
39
|
+
#
|
40
|
+
# # Feed the parser some XML
|
41
|
+
# parser.parse(File.open(ARGV[0]))
|
42
|
+
#
|
43
|
+
# Now my document handler will be called when each node starts, and when then document ends. To
|
44
|
+
# see what kinds of events are available, take a look at Nokogiri::XML::SAX::Document.
|
45
|
+
#
|
46
|
+
module SAX
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
3
51
|
require_relative "sax/document"
|
4
52
|
require_relative "sax/parser_context"
|
5
53
|
require_relative "sax/parser"
|
data/lib/nokogiri/xml/schema.rb
CHANGED
@@ -3,70 +3,137 @@
|
|
3
3
|
module Nokogiri
|
4
4
|
module XML
|
5
5
|
class << self
|
6
|
-
|
7
|
-
#
|
8
|
-
#
|
9
|
-
|
10
|
-
|
6
|
+
# :call-seq:
|
7
|
+
# Schema(input) → Nokogiri::XML::Schema
|
8
|
+
# Schema(input, parse_options) → Nokogiri::XML::Schema
|
9
|
+
#
|
10
|
+
# Convenience method for Nokogiri::XML::Schema.new
|
11
|
+
def Schema(...)
|
12
|
+
Schema.new(...)
|
11
13
|
end
|
12
14
|
end
|
13
15
|
|
14
|
-
|
15
|
-
# Nokogiri::XML::Schema is used for validating XML against a schema
|
16
|
-
# (usually from an xsd file).
|
16
|
+
# Nokogiri::XML::Schema is used for validating \XML against an \XSD schema definition.
|
17
17
|
#
|
18
|
-
#
|
18
|
+
# ⚠ Since v1.11.0, Schema treats inputs as *untrusted* by default, and so external entities are
|
19
|
+
# not resolved from the network (+http://+ or +ftp://+). When parsing a trusted document, the
|
20
|
+
# caller may turn off the +NONET+ option via the ParseOptions to (re-)enable external entity
|
21
|
+
# resolution over a network connection.
|
19
22
|
#
|
20
|
-
#
|
21
|
-
#
|
23
|
+
# 🛡 Before v1.11.0, documents were "trusted" by default during schema parsing which was counter
|
24
|
+
# to Nokogiri's "untrusted by default" security policy.
|
22
25
|
#
|
23
|
-
#
|
24
|
-
# doc = Nokogiri::XML(File.read(PO_XML_FILE))
|
26
|
+
# *Example:* Determine whether an \XML document is valid.
|
25
27
|
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
28
|
+
# schema = Nokogiri::XML::Schema.new(File.read(XSD_FILE))
|
29
|
+
# doc = Nokogiri::XML::Document.parse(File.read(XML_FILE))
|
30
|
+
# schema.valid?(doc) # Boolean
|
29
31
|
#
|
30
|
-
#
|
32
|
+
# *Example:* Validate an \XML document against an \XSD schema, and capture any errors that are found.
|
33
|
+
#
|
34
|
+
# schema = Nokogiri::XML::Schema.new(File.read(XSD_FILE))
|
35
|
+
# doc = Nokogiri::XML::Document.parse(File.read(XML_FILE))
|
36
|
+
# errors = schema.validate(doc) # Array<SyntaxError>
|
37
|
+
#
|
38
|
+
# *Example:* Validate an \XML document using a Document containing an \XSD schema definition.
|
39
|
+
#
|
40
|
+
# schema_doc = Nokogiri::XML::Document.parse(File.read(RELAX_NG_FILE))
|
41
|
+
# schema = Nokogiri::XML::Schema.from_document(schema_doc)
|
42
|
+
# doc = Nokogiri::XML::Document.parse(File.read(XML_FILE))
|
43
|
+
# schema.valid?(doc) # Boolean
|
31
44
|
#
|
32
|
-
# NOTE: As of v1.11.0, Schema treats inputs as UNTRUSTED by default, and so external entities
|
33
|
-
# are not resolved from the network (`http://` or `ftp://`). Previously, parsing treated
|
34
|
-
# documents as "trusted" by default which was counter to Nokogiri's "untrusted by default"
|
35
|
-
# security policy. If a document is trusted, then the caller may turn off the NONET option via
|
36
|
-
# the ParseOptions to re-enable external entity resolution over a network connection.
|
37
45
|
class Schema
|
38
|
-
#
|
46
|
+
# The errors found while parsing the \XSD
|
47
|
+
#
|
48
|
+
# [Returns] Array<Nokogiri::XML::SyntaxError>
|
39
49
|
attr_accessor :errors
|
40
|
-
|
50
|
+
|
51
|
+
# The options used to parse the schema
|
52
|
+
#
|
53
|
+
# [Returns] Nokogiri::XML::ParseOptions
|
41
54
|
attr_accessor :parse_options
|
42
55
|
|
43
|
-
|
44
|
-
#
|
45
|
-
#
|
46
|
-
|
47
|
-
|
56
|
+
# :call-seq:
|
57
|
+
# new(input) → Nokogiri::XML::Schema
|
58
|
+
# new(input, parse_options) → Nokogiri::XML::Schema
|
59
|
+
#
|
60
|
+
# Parse an \XSD schema definition from a String or IO to create a new Nokogiri::XML::Schema
|
61
|
+
#
|
62
|
+
# [Parameters]
|
63
|
+
# - +input+ (String | IO) \XSD schema definition
|
64
|
+
# - +parse_options+ (Nokogiri::XML::ParseOptions)
|
65
|
+
# Defaults to Nokogiri::XML::ParseOptions::DEFAULT_SCHEMA
|
66
|
+
#
|
67
|
+
# [Returns] Nokogiri::XML::Schema
|
68
|
+
#
|
69
|
+
def self.new(input, parse_options_ = ParseOptions::DEFAULT_SCHEMA, parse_options: parse_options_)
|
70
|
+
from_document(Nokogiri::XML::Document.parse(input), parse_options)
|
71
|
+
end
|
72
|
+
|
73
|
+
# :call-seq:
|
74
|
+
# read_memory(input) → Nokogiri::XML::Schema
|
75
|
+
# read_memory(input, parse_options) → Nokogiri::XML::Schema
|
76
|
+
#
|
77
|
+
# Convenience method for Nokogiri::XML::Schema.new
|
78
|
+
def self.read_memory(...)
|
79
|
+
# TODO deprecate this method
|
80
|
+
new(...)
|
48
81
|
end
|
49
82
|
|
50
|
-
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
83
|
+
#
|
84
|
+
# :call-seq: validate(input) → Array<SyntaxError>
|
85
|
+
#
|
86
|
+
# Validate +input+ and return any errors that are found.
|
87
|
+
#
|
88
|
+
# [Parameters]
|
89
|
+
# - +input+ (Nokogiri::XML::Document | String)
|
90
|
+
# A parsed document, or a string containing a local filename.
|
91
|
+
#
|
92
|
+
# [Returns] Array<SyntaxError>
|
93
|
+
#
|
94
|
+
# *Example:* Validate an existing XML::Document, and capture any errors that are found.
|
95
|
+
#
|
96
|
+
# schema = Nokogiri::XML::Schema.new(File.read(XSD_FILE))
|
97
|
+
# errors = schema.validate(document)
|
98
|
+
#
|
99
|
+
# *Example:* Validate an \XML document on disk, and capture any errors that are found.
|
100
|
+
#
|
101
|
+
# schema = Nokogiri::XML::Schema.new(File.read(XSD_FILE))
|
102
|
+
# errors = schema.validate("/path/to/file.xml")
|
103
|
+
#
|
104
|
+
def validate(input)
|
105
|
+
if input.is_a?(Nokogiri::XML::Document)
|
106
|
+
validate_document(input)
|
107
|
+
elsif File.file?(input)
|
108
|
+
validate_file(input)
|
60
109
|
else
|
61
|
-
raise ArgumentError, "Must provide Nokogiri::
|
110
|
+
raise ArgumentError, "Must provide Nokogiri::XML::Document or the name of an existing file"
|
62
111
|
end
|
63
112
|
end
|
64
113
|
|
65
|
-
|
66
|
-
#
|
67
|
-
#
|
68
|
-
|
69
|
-
|
114
|
+
#
|
115
|
+
# :call-seq: valid?(input) → Boolean
|
116
|
+
#
|
117
|
+
# Validate +input+ and return a Boolean indicating whether the document is valid
|
118
|
+
#
|
119
|
+
# [Parameters]
|
120
|
+
# - +input+ (Nokogiri::XML::Document | String)
|
121
|
+
# A parsed document, or a string containing a local filename.
|
122
|
+
#
|
123
|
+
# [Returns] Boolean
|
124
|
+
#
|
125
|
+
# *Example:* Validate an existing XML::Document
|
126
|
+
#
|
127
|
+
# schema = Nokogiri::XML::Schema.new(File.read(XSD_FILE))
|
128
|
+
# return unless schema.valid?(document)
|
129
|
+
#
|
130
|
+
# *Example:* Validate an \XML document on disk
|
131
|
+
#
|
132
|
+
# schema = Nokogiri::XML::Schema.new(File.read(XSD_FILE))
|
133
|
+
# return unless schema.valid?("/path/to/file.xml")
|
134
|
+
#
|
135
|
+
def valid?(input)
|
136
|
+
validate(input).empty?
|
70
137
|
end
|
71
138
|
end
|
72
139
|
end
|
@@ -207,35 +207,26 @@ module Nokogiri
|
|
207
207
|
|
208
208
|
private
|
209
209
|
|
210
|
-
def
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
def xpath_internal(node, paths, handler, ns, binds)
|
215
|
-
document = node.document
|
216
|
-
return NodeSet.new(document) unless document
|
217
|
-
|
218
|
-
if paths.length == 1
|
219
|
-
return xpath_impl(node, paths.first, handler, ns, binds)
|
210
|
+
def extract_params(params) # :nodoc:
|
211
|
+
handler = params.find do |param|
|
212
|
+
![Hash, String, Symbol].include?(param.class)
|
220
213
|
end
|
214
|
+
params -= [handler] if handler
|
221
215
|
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
216
|
+
hashes = []
|
217
|
+
while Hash === params.last || params.last.nil?
|
218
|
+
hashes << params.pop
|
219
|
+
break if params.empty?
|
226
220
|
end
|
227
|
-
|
221
|
+
ns, binds = hashes.reverse
|
228
222
|
|
229
|
-
|
230
|
-
ctx = XPathContext.new(node)
|
231
|
-
ctx.register_namespaces(ns)
|
232
|
-
path = path.gsub("xmlns:", " :") unless Nokogiri.uses_libxml?
|
223
|
+
ns ||= document.root&.namespaces || {}
|
233
224
|
|
234
|
-
|
235
|
-
|
236
|
-
end
|
225
|
+
[params, handler, ns, binds]
|
226
|
+
end
|
237
227
|
|
238
|
-
|
228
|
+
def css_internal(node, rules, handler, ns)
|
229
|
+
xpath_internal(node, css_rules_to_xpath(rules, ns), handler, ns, nil)
|
239
230
|
end
|
240
231
|
|
241
232
|
def css_rules_to_xpath(rules, ns)
|
@@ -243,35 +234,40 @@ module Nokogiri
|
|
243
234
|
end
|
244
235
|
|
245
236
|
def xpath_query_from_css_rule(rule, ns)
|
246
|
-
visitor = Nokogiri::CSS::XPathVisitor.new(
|
247
|
-
builtins: Nokogiri::CSS::XPathVisitor::BuiltinsConfig::OPTIMAL,
|
248
|
-
doctype: document.xpath_doctype,
|
249
|
-
)
|
250
237
|
self.class::IMPLIED_XPATH_CONTEXTS.map do |implied_xpath_context|
|
251
|
-
CSS.
|
238
|
+
visitor = Nokogiri::CSS::XPathVisitor.new(
|
239
|
+
builtins: Nokogiri::CSS::XPathVisitor::BuiltinsConfig::OPTIMAL,
|
240
|
+
doctype: document.xpath_doctype,
|
252
241
|
prefix: implied_xpath_context,
|
253
|
-
|
254
|
-
|
255
|
-
|
242
|
+
namespaces: ns,
|
243
|
+
)
|
244
|
+
CSS.xpath_for(rule.to_s, visitor: visitor)
|
256
245
|
end.join(" | ")
|
257
246
|
end
|
258
247
|
|
259
|
-
def
|
260
|
-
|
261
|
-
|
248
|
+
def xpath_internal(node, paths, handler, ns, binds)
|
249
|
+
document = node.document
|
250
|
+
return NodeSet.new(document) unless document
|
251
|
+
|
252
|
+
if paths.length == 1
|
253
|
+
return xpath_impl(node, paths.first, handler, ns, binds)
|
262
254
|
end
|
263
|
-
params -= [handler] if handler
|
264
255
|
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
256
|
+
NodeSet.new(document) do |combined|
|
257
|
+
paths.each do |path|
|
258
|
+
xpath_impl(node, path, handler, ns, binds).each { |set| combined << set }
|
259
|
+
end
|
269
260
|
end
|
270
|
-
|
261
|
+
end
|
271
262
|
|
272
|
-
|
263
|
+
def xpath_impl(node, path, handler, ns, binds)
|
264
|
+
context = XPathContext.new(node)
|
265
|
+
context.register_namespaces(ns)
|
266
|
+
context.register_variables(binds)
|
273
267
|
|
274
|
-
|
268
|
+
path = path.gsub("xmlns:", " :") unless Nokogiri.uses_libxml?
|
269
|
+
|
270
|
+
context.evaluate(path, handler)
|
275
271
|
end
|
276
272
|
end
|
277
273
|
end
|
@@ -6,11 +6,33 @@ module Nokogiri
|
|
6
6
|
# This class provides information about XML SyntaxErrors. These
|
7
7
|
# exceptions are typically stored on Nokogiri::XML::Document#errors.
|
8
8
|
class SyntaxError < ::Nokogiri::SyntaxError
|
9
|
+
class << self
|
10
|
+
def aggregate(errors)
|
11
|
+
return nil if errors.empty?
|
12
|
+
return errors.first if errors.length == 1
|
13
|
+
|
14
|
+
messages = ["Multiple errors encountered:"]
|
15
|
+
errors.each do |error|
|
16
|
+
messages << error.to_s
|
17
|
+
end
|
18
|
+
new(messages.join("\n"))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
9
22
|
attr_reader :domain
|
10
23
|
attr_reader :code
|
11
24
|
attr_reader :level
|
12
25
|
attr_reader :file
|
13
26
|
attr_reader :line
|
27
|
+
|
28
|
+
# The XPath path of the node that caused the error when validating a `Nokogiri::XML::Document`.
|
29
|
+
#
|
30
|
+
# This attribute will only be non-nil when the error is emitted by `Schema#validate` on
|
31
|
+
# Document objects. It will return `nil` for DOM parsing errors and for errors emitted during
|
32
|
+
# Schema validation of files.
|
33
|
+
#
|
34
|
+
# ⚠ `#path` is not supported on JRuby, where it will always return `nil`.
|
35
|
+
attr_reader :path
|
14
36
|
attr_reader :str1
|
15
37
|
attr_reader :str2
|
16
38
|
attr_reader :str3
|
@@ -6,9 +6,20 @@ module Nokogiri
|
|
6
6
|
###
|
7
7
|
# Register namespaces in +namespaces+
|
8
8
|
def register_namespaces(namespaces)
|
9
|
-
namespaces.each do |
|
10
|
-
|
11
|
-
|
9
|
+
namespaces.each do |key, value|
|
10
|
+
key = key.to_s.gsub(/.*:/, "") # strip off 'xmlns:' or 'xml:'
|
11
|
+
|
12
|
+
register_ns(key, value)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def register_variables(binds)
|
17
|
+
return if binds.nil?
|
18
|
+
|
19
|
+
binds.each do |key, value|
|
20
|
+
key = key.to_s
|
21
|
+
|
22
|
+
register_variable(key, value)
|
12
23
|
end
|
13
24
|
end
|
14
25
|
end
|
data/lib/nokogiri/xml.rb
CHANGED
@@ -2,10 +2,9 @@
|
|
2
2
|
|
3
3
|
module Nokogiri
|
4
4
|
class << self
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
Nokogiri::XML::Document.parse(thing, url, encoding, options, &block)
|
5
|
+
# Convenience method for Nokogiri::XML::Document.parse
|
6
|
+
def XML(...)
|
7
|
+
Nokogiri::XML::Document.parse(...)
|
9
8
|
end
|
10
9
|
end
|
11
10
|
|
@@ -16,31 +15,21 @@ module Nokogiri
|
|
16
15
|
XML_C14N_EXCLUSIVE_1_0 = 1
|
17
16
|
# C14N 1.1 spec canonicalization
|
18
17
|
XML_C14N_1_1 = 2
|
19
|
-
class << self
|
20
|
-
###
|
21
|
-
# Parse an XML document using the Nokogiri::XML::Reader API. See
|
22
|
-
# Nokogiri::XML::Reader for mor information
|
23
|
-
def Reader(string_or_io, url = nil, encoding = nil, options = ParseOptions::STRICT)
|
24
|
-
options = Nokogiri::XML::ParseOptions.new(options) if Integer === options
|
25
|
-
yield options if block_given?
|
26
|
-
|
27
|
-
if string_or_io.respond_to?(:read)
|
28
|
-
return Reader.from_io(string_or_io, url, encoding, options.to_i)
|
29
|
-
end
|
30
18
|
|
31
|
-
|
19
|
+
class << self
|
20
|
+
# Convenience method for Nokogiri::XML::Reader.new
|
21
|
+
def Reader(...)
|
22
|
+
Reader.new(...)
|
32
23
|
end
|
33
24
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
Document.parse(thing, url, encoding, options, &block)
|
25
|
+
# Convenience method for Nokogiri::XML::Document.parse
|
26
|
+
def parse(...)
|
27
|
+
Document.parse(...)
|
38
28
|
end
|
39
29
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
XML::DocumentFragment.parse(string, options, &block)
|
30
|
+
# Convenience method for Nokogiri::XML::DocumentFragment.parse
|
31
|
+
def fragment(...)
|
32
|
+
XML::DocumentFragment.parse(...)
|
44
33
|
end
|
45
34
|
end
|
46
35
|
end
|
data/lib/nokogiri/xslt.rb
CHANGED
@@ -3,15 +3,9 @@
|
|
3
3
|
|
4
4
|
module Nokogiri
|
5
5
|
class << self
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
# Example:
|
10
|
-
#
|
11
|
-
# xslt = Nokogiri::XSLT(File.read(ARGV[0]))
|
12
|
-
#
|
13
|
-
def XSLT(stylesheet, modules = {})
|
14
|
-
XSLT.parse(stylesheet, modules)
|
6
|
+
# Convenience method for Nokogiri::XSLT.parse
|
7
|
+
def XSLT(...)
|
8
|
+
XSLT.parse(...)
|
15
9
|
end
|
16
10
|
end
|
17
11
|
|
@@ -7,10 +7,9 @@ module XSD
|
|
7
7
|
###
|
8
8
|
# Nokogiri XML parser for soap4r.
|
9
9
|
#
|
10
|
-
# Nokogiri may be used as the XML parser in soap4r.
|
11
|
-
#
|
12
|
-
#
|
13
|
-
# required to use Nokogiri as the XML parser.
|
10
|
+
# Nokogiri may be used as the XML parser in soap4r. Require 'xsd/xmlparser/nokogiri' in your
|
11
|
+
# soap4r applications, and soap4r will use Nokogiri as its XML parser. No other changes should
|
12
|
+
# be required to use Nokogiri as the XML parser.
|
14
13
|
#
|
15
14
|
# Example (using UW ITS Web Services):
|
16
15
|
#
|