nokogiri 1.18.0.rc1-x86_64-linux-gnu

Sign up to get free protection for your applications and to get access to all the features.
Files changed (203) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +38 -0
  3. data/LICENSE-DEPENDENCIES.md +2224 -0
  4. data/LICENSE.md +9 -0
  5. data/README.md +293 -0
  6. data/bin/nokogiri +131 -0
  7. data/dependencies.yml +42 -0
  8. data/ext/nokogiri/depend +38 -0
  9. data/ext/nokogiri/extconf.rb +1173 -0
  10. data/ext/nokogiri/gumbo.c +610 -0
  11. data/ext/nokogiri/html4_document.c +171 -0
  12. data/ext/nokogiri/html4_element_description.c +299 -0
  13. data/ext/nokogiri/html4_entity_lookup.c +37 -0
  14. data/ext/nokogiri/html4_sax_parser.c +40 -0
  15. data/ext/nokogiri/html4_sax_parser_context.c +98 -0
  16. data/ext/nokogiri/html4_sax_push_parser.c +96 -0
  17. data/ext/nokogiri/include/libexslt/exslt.h +108 -0
  18. data/ext/nokogiri/include/libexslt/exsltconfig.h +70 -0
  19. data/ext/nokogiri/include/libexslt/exsltexports.h +63 -0
  20. data/ext/nokogiri/include/libxml2/libxml/HTMLparser.h +336 -0
  21. data/ext/nokogiri/include/libxml2/libxml/HTMLtree.h +147 -0
  22. data/ext/nokogiri/include/libxml2/libxml/SAX.h +202 -0
  23. data/ext/nokogiri/include/libxml2/libxml/SAX2.h +171 -0
  24. data/ext/nokogiri/include/libxml2/libxml/c14n.h +115 -0
  25. data/ext/nokogiri/include/libxml2/libxml/catalog.h +182 -0
  26. data/ext/nokogiri/include/libxml2/libxml/chvalid.h +230 -0
  27. data/ext/nokogiri/include/libxml2/libxml/debugXML.h +217 -0
  28. data/ext/nokogiri/include/libxml2/libxml/dict.h +82 -0
  29. data/ext/nokogiri/include/libxml2/libxml/encoding.h +244 -0
  30. data/ext/nokogiri/include/libxml2/libxml/entities.h +166 -0
  31. data/ext/nokogiri/include/libxml2/libxml/globals.h +41 -0
  32. data/ext/nokogiri/include/libxml2/libxml/hash.h +251 -0
  33. data/ext/nokogiri/include/libxml2/libxml/list.h +137 -0
  34. data/ext/nokogiri/include/libxml2/libxml/nanoftp.h +186 -0
  35. data/ext/nokogiri/include/libxml2/libxml/nanohttp.h +98 -0
  36. data/ext/nokogiri/include/libxml2/libxml/parser.h +1390 -0
  37. data/ext/nokogiri/include/libxml2/libxml/parserInternals.h +671 -0
  38. data/ext/nokogiri/include/libxml2/libxml/pattern.h +106 -0
  39. data/ext/nokogiri/include/libxml2/libxml/relaxng.h +219 -0
  40. data/ext/nokogiri/include/libxml2/libxml/schemasInternals.h +959 -0
  41. data/ext/nokogiri/include/libxml2/libxml/schematron.h +143 -0
  42. data/ext/nokogiri/include/libxml2/libxml/threads.h +87 -0
  43. data/ext/nokogiri/include/libxml2/libxml/tree.h +1382 -0
  44. data/ext/nokogiri/include/libxml2/libxml/uri.h +106 -0
  45. data/ext/nokogiri/include/libxml2/libxml/valid.h +477 -0
  46. data/ext/nokogiri/include/libxml2/libxml/xinclude.h +136 -0
  47. data/ext/nokogiri/include/libxml2/libxml/xlink.h +189 -0
  48. data/ext/nokogiri/include/libxml2/libxml/xmlIO.h +438 -0
  49. data/ext/nokogiri/include/libxml2/libxml/xmlautomata.h +146 -0
  50. data/ext/nokogiri/include/libxml2/libxml/xmlerror.h +962 -0
  51. data/ext/nokogiri/include/libxml2/libxml/xmlexports.h +146 -0
  52. data/ext/nokogiri/include/libxml2/libxml/xmlmemory.h +188 -0
  53. data/ext/nokogiri/include/libxml2/libxml/xmlmodule.h +57 -0
  54. data/ext/nokogiri/include/libxml2/libxml/xmlreader.h +436 -0
  55. data/ext/nokogiri/include/libxml2/libxml/xmlregexp.h +215 -0
  56. data/ext/nokogiri/include/libxml2/libxml/xmlsave.h +102 -0
  57. data/ext/nokogiri/include/libxml2/libxml/xmlschemas.h +249 -0
  58. data/ext/nokogiri/include/libxml2/libxml/xmlschemastypes.h +152 -0
  59. data/ext/nokogiri/include/libxml2/libxml/xmlstring.h +140 -0
  60. data/ext/nokogiri/include/libxml2/libxml/xmlunicode.h +366 -0
  61. data/ext/nokogiri/include/libxml2/libxml/xmlversion.h +347 -0
  62. data/ext/nokogiri/include/libxml2/libxml/xmlwriter.h +489 -0
  63. data/ext/nokogiri/include/libxml2/libxml/xpath.h +579 -0
  64. data/ext/nokogiri/include/libxml2/libxml/xpathInternals.h +633 -0
  65. data/ext/nokogiri/include/libxml2/libxml/xpointer.h +138 -0
  66. data/ext/nokogiri/include/libxslt/attributes.h +39 -0
  67. data/ext/nokogiri/include/libxslt/documents.h +93 -0
  68. data/ext/nokogiri/include/libxslt/extensions.h +262 -0
  69. data/ext/nokogiri/include/libxslt/extra.h +72 -0
  70. data/ext/nokogiri/include/libxslt/functions.h +78 -0
  71. data/ext/nokogiri/include/libxslt/imports.h +75 -0
  72. data/ext/nokogiri/include/libxslt/keys.h +53 -0
  73. data/ext/nokogiri/include/libxslt/namespaces.h +68 -0
  74. data/ext/nokogiri/include/libxslt/numbersInternals.h +73 -0
  75. data/ext/nokogiri/include/libxslt/pattern.h +84 -0
  76. data/ext/nokogiri/include/libxslt/preproc.h +43 -0
  77. data/ext/nokogiri/include/libxslt/security.h +104 -0
  78. data/ext/nokogiri/include/libxslt/templates.h +77 -0
  79. data/ext/nokogiri/include/libxslt/transform.h +207 -0
  80. data/ext/nokogiri/include/libxslt/variables.h +118 -0
  81. data/ext/nokogiri/include/libxslt/xslt.h +110 -0
  82. data/ext/nokogiri/include/libxslt/xsltInternals.h +1995 -0
  83. data/ext/nokogiri/include/libxslt/xsltconfig.h +146 -0
  84. data/ext/nokogiri/include/libxslt/xsltexports.h +64 -0
  85. data/ext/nokogiri/include/libxslt/xsltlocale.h +44 -0
  86. data/ext/nokogiri/include/libxslt/xsltutils.h +343 -0
  87. data/ext/nokogiri/libxml2_polyfill.c +114 -0
  88. data/ext/nokogiri/nokogiri.c +294 -0
  89. data/ext/nokogiri/nokogiri.h +238 -0
  90. data/ext/nokogiri/test_global_handlers.c +40 -0
  91. data/ext/nokogiri/xml_attr.c +103 -0
  92. data/ext/nokogiri/xml_attribute_decl.c +70 -0
  93. data/ext/nokogiri/xml_cdata.c +62 -0
  94. data/ext/nokogiri/xml_comment.c +57 -0
  95. data/ext/nokogiri/xml_document.c +784 -0
  96. data/ext/nokogiri/xml_document_fragment.c +29 -0
  97. data/ext/nokogiri/xml_dtd.c +208 -0
  98. data/ext/nokogiri/xml_element_content.c +131 -0
  99. data/ext/nokogiri/xml_element_decl.c +69 -0
  100. data/ext/nokogiri/xml_encoding_handler.c +112 -0
  101. data/ext/nokogiri/xml_entity_decl.c +112 -0
  102. data/ext/nokogiri/xml_entity_reference.c +50 -0
  103. data/ext/nokogiri/xml_namespace.c +181 -0
  104. data/ext/nokogiri/xml_node.c +2459 -0
  105. data/ext/nokogiri/xml_node_set.c +518 -0
  106. data/ext/nokogiri/xml_processing_instruction.c +54 -0
  107. data/ext/nokogiri/xml_reader.c +777 -0
  108. data/ext/nokogiri/xml_relax_ng.c +149 -0
  109. data/ext/nokogiri/xml_sax_parser.c +403 -0
  110. data/ext/nokogiri/xml_sax_parser_context.c +390 -0
  111. data/ext/nokogiri/xml_sax_push_parser.c +206 -0
  112. data/ext/nokogiri/xml_schema.c +226 -0
  113. data/ext/nokogiri/xml_syntax_error.c +93 -0
  114. data/ext/nokogiri/xml_text.c +59 -0
  115. data/ext/nokogiri/xml_xpath_context.c +502 -0
  116. data/ext/nokogiri/xslt_stylesheet.c +421 -0
  117. data/gumbo-parser/CHANGES.md +63 -0
  118. data/gumbo-parser/Makefile +129 -0
  119. data/gumbo-parser/THANKS +27 -0
  120. data/lib/nokogiri/3.1/nokogiri.so +0 -0
  121. data/lib/nokogiri/3.2/nokogiri.so +0 -0
  122. data/lib/nokogiri/3.3/nokogiri.so +0 -0
  123. data/lib/nokogiri/3.4/nokogiri.so +0 -0
  124. data/lib/nokogiri/class_resolver.rb +67 -0
  125. data/lib/nokogiri/css/node.rb +58 -0
  126. data/lib/nokogiri/css/parser.rb +772 -0
  127. data/lib/nokogiri/css/parser.y +277 -0
  128. data/lib/nokogiri/css/parser_extras.rb +36 -0
  129. data/lib/nokogiri/css/selector_cache.rb +38 -0
  130. data/lib/nokogiri/css/syntax_error.rb +9 -0
  131. data/lib/nokogiri/css/tokenizer.rb +155 -0
  132. data/lib/nokogiri/css/tokenizer.rex +57 -0
  133. data/lib/nokogiri/css/xpath_visitor.rb +375 -0
  134. data/lib/nokogiri/css.rb +132 -0
  135. data/lib/nokogiri/decorators/slop.rb +42 -0
  136. data/lib/nokogiri/encoding_handler.rb +57 -0
  137. data/lib/nokogiri/extension.rb +32 -0
  138. data/lib/nokogiri/gumbo.rb +15 -0
  139. data/lib/nokogiri/html.rb +48 -0
  140. data/lib/nokogiri/html4/builder.rb +37 -0
  141. data/lib/nokogiri/html4/document.rb +235 -0
  142. data/lib/nokogiri/html4/document_fragment.rb +166 -0
  143. data/lib/nokogiri/html4/element_description.rb +25 -0
  144. data/lib/nokogiri/html4/element_description_defaults.rb +2040 -0
  145. data/lib/nokogiri/html4/encoding_reader.rb +121 -0
  146. data/lib/nokogiri/html4/entity_lookup.rb +15 -0
  147. data/lib/nokogiri/html4/sax/parser.rb +48 -0
  148. data/lib/nokogiri/html4/sax/parser_context.rb +15 -0
  149. data/lib/nokogiri/html4/sax/push_parser.rb +37 -0
  150. data/lib/nokogiri/html4.rb +42 -0
  151. data/lib/nokogiri/html5/builder.rb +40 -0
  152. data/lib/nokogiri/html5/document.rb +199 -0
  153. data/lib/nokogiri/html5/document_fragment.rb +200 -0
  154. data/lib/nokogiri/html5/node.rb +103 -0
  155. data/lib/nokogiri/html5.rb +368 -0
  156. data/lib/nokogiri/jruby/dependencies.rb +3 -0
  157. data/lib/nokogiri/jruby/nokogiri_jars.rb +43 -0
  158. data/lib/nokogiri/syntax_error.rb +6 -0
  159. data/lib/nokogiri/version/constant.rb +6 -0
  160. data/lib/nokogiri/version/info.rb +224 -0
  161. data/lib/nokogiri/version.rb +4 -0
  162. data/lib/nokogiri/xml/attr.rb +66 -0
  163. data/lib/nokogiri/xml/attribute_decl.rb +22 -0
  164. data/lib/nokogiri/xml/builder.rb +494 -0
  165. data/lib/nokogiri/xml/cdata.rb +13 -0
  166. data/lib/nokogiri/xml/character_data.rb +9 -0
  167. data/lib/nokogiri/xml/document.rb +514 -0
  168. data/lib/nokogiri/xml/document_fragment.rb +276 -0
  169. data/lib/nokogiri/xml/dtd.rb +34 -0
  170. data/lib/nokogiri/xml/element_content.rb +46 -0
  171. data/lib/nokogiri/xml/element_decl.rb +17 -0
  172. data/lib/nokogiri/xml/entity_decl.rb +23 -0
  173. data/lib/nokogiri/xml/entity_reference.rb +20 -0
  174. data/lib/nokogiri/xml/namespace.rb +57 -0
  175. data/lib/nokogiri/xml/node/save_options.rb +76 -0
  176. data/lib/nokogiri/xml/node.rb +1650 -0
  177. data/lib/nokogiri/xml/node_set.rb +449 -0
  178. data/lib/nokogiri/xml/notation.rb +19 -0
  179. data/lib/nokogiri/xml/parse_options.rb +213 -0
  180. data/lib/nokogiri/xml/pp/character_data.rb +21 -0
  181. data/lib/nokogiri/xml/pp/node.rb +73 -0
  182. data/lib/nokogiri/xml/pp.rb +4 -0
  183. data/lib/nokogiri/xml/processing_instruction.rb +11 -0
  184. data/lib/nokogiri/xml/reader.rb +139 -0
  185. data/lib/nokogiri/xml/relax_ng.rb +75 -0
  186. data/lib/nokogiri/xml/sax/document.rb +258 -0
  187. data/lib/nokogiri/xml/sax/parser.rb +199 -0
  188. data/lib/nokogiri/xml/sax/parser_context.rb +129 -0
  189. data/lib/nokogiri/xml/sax/push_parser.rb +64 -0
  190. data/lib/nokogiri/xml/sax.rb +54 -0
  191. data/lib/nokogiri/xml/schema.rb +140 -0
  192. data/lib/nokogiri/xml/searchable.rb +297 -0
  193. data/lib/nokogiri/xml/syntax_error.rb +94 -0
  194. data/lib/nokogiri/xml/text.rb +11 -0
  195. data/lib/nokogiri/xml/xpath/syntax_error.rb +13 -0
  196. data/lib/nokogiri/xml/xpath.rb +21 -0
  197. data/lib/nokogiri/xml/xpath_context.rb +49 -0
  198. data/lib/nokogiri/xml.rb +65 -0
  199. data/lib/nokogiri/xslt/stylesheet.rb +49 -0
  200. data/lib/nokogiri/xslt.rb +129 -0
  201. data/lib/nokogiri.rb +128 -0
  202. data/lib/xsd/xmlparser/nokogiri.rb +105 -0
  203. metadata +324 -0
@@ -0,0 +1,297 @@
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Nokogiri
5
+ module XML
6
+ #
7
+ # The Searchable module declares the interface used for searching your DOM.
8
+ #
9
+ # It implements the public methods #search, #css, and #xpath,
10
+ # as well as allowing specific implementations to specialize some
11
+ # of the important behaviors.
12
+ #
13
+ module Searchable
14
+ # Regular expression used by Searchable#search to determine if a query
15
+ # string is CSS or XPath
16
+ LOOKS_LIKE_XPATH = %r{^(\./|/|\.\.|\.$)}
17
+
18
+ # :section: Searching via XPath or CSS Queries
19
+
20
+ ###
21
+ # call-seq:
22
+ # search(*paths, [namespace-bindings, xpath-variable-bindings, custom-handler-class])
23
+ #
24
+ # Search this object for +paths+. +paths+ must be one or more XPath or CSS queries:
25
+ #
26
+ # node.search("div.employee", ".//title")
27
+ #
28
+ # A hash of namespace bindings may be appended:
29
+ #
30
+ # node.search('.//bike:tire', {'bike' => 'http://schwinn.com/'})
31
+ # node.search('bike|tire', {'bike' => 'http://schwinn.com/'})
32
+ #
33
+ # For XPath queries, a hash of variable bindings may also be appended to the namespace
34
+ # bindings. For example:
35
+ #
36
+ # node.search('.//address[@domestic=$value]', nil, {:value => 'Yes'})
37
+ #
38
+ # 💡 Custom XPath functions and CSS pseudo-selectors may also be defined. To define custom
39
+ # functions create a class and implement the function you want to define, which will be in the
40
+ # `nokogiri` namespace in XPath queries.
41
+ #
42
+ # The first argument to the method will be the current matching NodeSet. Any other arguments
43
+ # are ones that you pass in. Note that this class may appear anywhere in the argument
44
+ # list. For example:
45
+ #
46
+ # handler = Class.new {
47
+ # def regex node_set, regex
48
+ # node_set.find_all { |node| node['some_attribute'] =~ /#{regex}/ }
49
+ # end
50
+ # }.new
51
+ # node.search('.//title[nokogiri:regex(., "\w+")]', 'div.employee:regex("[0-9]+")', handler)
52
+ #
53
+ # See Searchable#xpath and Searchable#css for further usage help.
54
+ def search(*args)
55
+ paths, handler, ns, binds = extract_params(args)
56
+
57
+ xpaths = paths.map(&:to_s).map do |path|
58
+ LOOKS_LIKE_XPATH.match?(path) ? path : xpath_query_from_css_rule(path, ns)
59
+ end.flatten.uniq
60
+
61
+ xpath(*(xpaths + [ns, handler, binds].compact))
62
+ end
63
+
64
+ alias_method :/, :search
65
+
66
+ ###
67
+ # call-seq:
68
+ # at(*paths, [namespace-bindings, xpath-variable-bindings, custom-handler-class])
69
+ #
70
+ # Search this object for +paths+, and return only the first
71
+ # result. +paths+ must be one or more XPath or CSS queries.
72
+ #
73
+ # See Searchable#search for more information.
74
+ def at(*args)
75
+ search(*args).first
76
+ end
77
+
78
+ alias_method :%, :at
79
+
80
+ ###
81
+ # call-seq:
82
+ # css(*rules, [namespace-bindings, custom-pseudo-class])
83
+ #
84
+ # Search this object for CSS +rules+. +rules+ must be one or more CSS
85
+ # selectors. For example:
86
+ #
87
+ # node.css('title')
88
+ # node.css('body h1.bold')
89
+ # node.css('div + p.green', 'div#one')
90
+ #
91
+ # A hash of namespace bindings may be appended. For example:
92
+ #
93
+ # node.css('bike|tire', {'bike' => 'http://schwinn.com/'})
94
+ #
95
+ # 💡 Custom CSS pseudo classes may also be defined which are mapped to a custom XPath
96
+ # function. To define custom pseudo classes, create a class and implement the custom pseudo
97
+ # class you want defined. The first argument to the method will be the matching context
98
+ # NodeSet. Any other arguments are ones that you pass in. For example:
99
+ #
100
+ # handler = Class.new {
101
+ # def regex(node_set, regex)
102
+ # node_set.find_all { |node| node['some_attribute'] =~ /#{regex}/ }
103
+ # end
104
+ # }.new
105
+ # node.css('title:regex("\w+")', handler)
106
+ #
107
+ # 💡 Some XPath syntax is supported in CSS queries. For example, to query for an attribute:
108
+ #
109
+ # node.css('img > @href') # returns all +href+ attributes on an +img+ element
110
+ # node.css('img / @href') # same
111
+ #
112
+ # # ⚠ this returns +class+ attributes from all +div+ elements AND THEIR CHILDREN!
113
+ # node.css('div @class')
114
+ #
115
+ # node.css
116
+ #
117
+ # 💡 Array-like syntax is supported in CSS queries as an alternative to using +:nth-child()+.
118
+ #
119
+ # ⚠ NOTE that indices are 1-based like +:nth-child+ and not 0-based like Ruby Arrays. For
120
+ # example:
121
+ #
122
+ # # equivalent to 'li:nth-child(2)'
123
+ # node.css('li[2]') # retrieve the second li element in a list
124
+ #
125
+ # ⚠ NOTE that the CSS query string is case-sensitive with regards to your document type. HTML
126
+ # tags will match only lowercase CSS queries, so if you search for "H1" in an HTML document,
127
+ # you'll never find anything. However, "H1" might be found in an XML document, where tags
128
+ # names are case-sensitive (e.g., "H1" is distinct from "h1").
129
+ def css(*args)
130
+ rules, handler, ns, _ = extract_params(args)
131
+
132
+ css_internal(self, rules, handler, ns)
133
+ end
134
+
135
+ ##
136
+ # call-seq:
137
+ # at_css(*rules, [namespace-bindings, custom-pseudo-class])
138
+ #
139
+ # Search this object for CSS +rules+, and return only the first
140
+ # match. +rules+ must be one or more CSS selectors.
141
+ #
142
+ # See Searchable#css for more information.
143
+ def at_css(*args)
144
+ css(*args).first
145
+ end
146
+
147
+ ###
148
+ # call-seq:
149
+ # xpath(*paths, [namespace-bindings, variable-bindings, custom-handler-class])
150
+ #
151
+ # Search this node for XPath +paths+. +paths+ must be one or more XPath
152
+ # queries.
153
+ #
154
+ # node.xpath('.//title')
155
+ #
156
+ # A hash of namespace bindings may be appended. For example:
157
+ #
158
+ # node.xpath('.//foo:name', {'foo' => 'http://example.org/'})
159
+ # node.xpath('.//xmlns:name', node.root.namespaces)
160
+ #
161
+ # A hash of variable bindings may also be appended to the namespace bindings. For example:
162
+ #
163
+ # node.xpath('.//address[@domestic=$value]', nil, {:value => 'Yes'})
164
+ #
165
+ # 💡 Custom XPath functions may also be defined. To define custom functions create a class and
166
+ # implement the function you want to define, which will be in the `nokogiri` namespace.
167
+ #
168
+ # The first argument to the method will be the current matching NodeSet. Any other arguments
169
+ # are ones that you pass in. Note that this class may appear anywhere in the argument
170
+ # list. For example:
171
+ #
172
+ # handler = Class.new {
173
+ # def regex(node_set, regex)
174
+ # node_set.find_all { |node| node['some_attribute'] =~ /#{regex}/ }
175
+ # end
176
+ # }.new
177
+ # node.xpath('.//title[nokogiri:regex(., "\w+")]', handler)
178
+ #
179
+ def xpath(*args)
180
+ paths, handler, ns, binds = extract_params(args)
181
+
182
+ xpath_internal(self, paths, handler, ns, binds)
183
+ end
184
+
185
+ ##
186
+ # call-seq:
187
+ # at_xpath(*paths, [namespace-bindings, variable-bindings, custom-handler-class])
188
+ #
189
+ # Search this node for XPath +paths+, and return only the first
190
+ # match. +paths+ must be one or more XPath queries.
191
+ #
192
+ # See Searchable#xpath for more information.
193
+ def at_xpath(*args)
194
+ xpath(*args).first
195
+ end
196
+
197
+ # :call-seq:
198
+ # >(selector) → NodeSet
199
+ #
200
+ # Search this node's immediate children using CSS selector +selector+
201
+ def >(selector) # rubocop:disable Naming/BinaryOperatorParameterName
202
+ ns = document.root&.namespaces || {}
203
+ xpath(CSS.xpath_for(selector, prefix: "./", ns: ns).first)
204
+ end
205
+
206
+ # :section:
207
+
208
+ private
209
+
210
+ def extract_params(params) # :nodoc:
211
+ handler = params.find do |param|
212
+ ![Hash, String, Symbol].include?(param.class)
213
+ end
214
+ params -= [handler] if handler
215
+
216
+ hashes = []
217
+ while Hash === params.last || params.last.nil?
218
+ hashes << params.pop
219
+ break if params.empty?
220
+ end
221
+ ns, binds = hashes.reverse
222
+
223
+ ns ||= document.root&.namespaces || {}
224
+
225
+ [params, handler, ns, binds]
226
+ end
227
+
228
+ def css_internal(node, rules, handler, ns)
229
+ xpath_internal(node, css_rules_to_xpath(rules, ns), handler, ns, nil)
230
+ end
231
+
232
+ def css_rules_to_xpath(rules, ns)
233
+ rules.map { |rule| xpath_query_from_css_rule(rule, ns) }
234
+ end
235
+
236
+ def xpath_query_from_css_rule(rule, ns)
237
+ self.class::IMPLIED_XPATH_CONTEXTS.map do |implied_xpath_context|
238
+ visitor = Nokogiri::CSS::XPathVisitor.new(
239
+ builtins: Nokogiri::CSS::XPathVisitor::BuiltinsConfig::OPTIMAL,
240
+ doctype: document.xpath_doctype,
241
+ prefix: implied_xpath_context,
242
+ namespaces: ns,
243
+ )
244
+ CSS.xpath_for(rule.to_s, visitor: visitor)
245
+ end.join(" | ")
246
+ end
247
+
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)
254
+ end
255
+
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
260
+ end
261
+ end
262
+
263
+ def xpath_impl(node, path, handler, ns, binds)
264
+ get_xpath_context(node) do |context|
265
+ context.register_namespaces(ns)
266
+ context.register_variables(binds)
267
+
268
+ path = path.gsub("xmlns:", " :") unless Nokogiri.uses_libxml?
269
+
270
+ context.evaluate(path, handler)
271
+ end
272
+ end
273
+
274
+ if Nokogiri.uses_libxml? && ENV["NOKOGIRI_DEOPTIMIZE_XPATH"].nil? # env var is an escape hatch
275
+ # optimized path
276
+ def get_xpath_context(node)
277
+ context = Thread.current.thread_variable_get(:nokogiri_xpath_context)
278
+ if context
279
+ context.node = node
280
+ else
281
+ context = Thread.current.thread_variable_set(:nokogiri_xpath_context, XPathContext.new(node))
282
+ end
283
+
284
+ begin
285
+ yield context
286
+ ensure
287
+ context.reset
288
+ end
289
+ end
290
+ else
291
+ def get_xpath_context(node)
292
+ yield XPathContext.new(node)
293
+ end
294
+ end
295
+ end
296
+ end
297
+ end
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nokogiri
4
+ module XML
5
+ ###
6
+ # This class provides information about XML SyntaxErrors. These
7
+ # exceptions are typically stored on Nokogiri::XML::Document#errors.
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
+
22
+ attr_reader :domain
23
+ attr_reader :code
24
+ attr_reader :level
25
+ attr_reader :file
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
36
+ attr_reader :str1
37
+ attr_reader :str2
38
+ attr_reader :str3
39
+ attr_reader :int1
40
+ attr_reader :column
41
+
42
+ ###
43
+ # return true if this is a non error
44
+ def none?
45
+ level == 0
46
+ end
47
+
48
+ ###
49
+ # return true if this is a warning
50
+ def warning?
51
+ level == 1
52
+ end
53
+
54
+ ###
55
+ # return true if this is an error
56
+ def error?
57
+ level == 2
58
+ end
59
+
60
+ ###
61
+ # return true if this error is fatal
62
+ def fatal?
63
+ level == 3
64
+ end
65
+
66
+ def to_s
67
+ message = super.chomp
68
+ [location_to_s, level_to_s, message]
69
+ .compact.join(": ")
70
+ .force_encoding(message.encoding)
71
+ end
72
+
73
+ private
74
+
75
+ def level_to_s
76
+ case level
77
+ when 3 then "FATAL"
78
+ when 2 then "ERROR"
79
+ when 1 then "WARNING"
80
+ end
81
+ end
82
+
83
+ def nil_or_zero?(attribute)
84
+ attribute.nil? || attribute.zero?
85
+ end
86
+
87
+ def location_to_s
88
+ return if nil_or_zero?(line) && nil_or_zero?(column)
89
+
90
+ "#{line}:#{column}"
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nokogiri
4
+ module XML
5
+ class Text < Nokogiri::XML::CharacterData
6
+ def content=(string)
7
+ self.native_content = string.to_s
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nokogiri
4
+ module XML
5
+ module XPath
6
+ class SyntaxError < XML::SyntaxError
7
+ def to_s
8
+ [super.chomp, str1].compact.join(": ")
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nokogiri
4
+ module XML
5
+ module XPath
6
+ # The XPath search prefix to search globally, +//+
7
+ GLOBAL_SEARCH_PREFIX = "//"
8
+
9
+ # The XPath search prefix to search direct descendants of the root element, +/+
10
+ ROOT_SEARCH_PREFIX = "/"
11
+
12
+ # The XPath search prefix to search direct descendants of the current element, +./+
13
+ CURRENT_SEARCH_PREFIX = "./"
14
+
15
+ # The XPath search prefix to search anywhere in the current element's subtree, +.//+
16
+ SUBTREE_SEARCH_PREFIX = ".//"
17
+ end
18
+ end
19
+ end
20
+
21
+ require_relative "xpath/syntax_error"
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nokogiri
4
+ module XML
5
+ class XPathContext
6
+ ###
7
+ # Register namespaces in +namespaces+
8
+ def register_namespaces(namespaces)
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)
23
+ end
24
+ end
25
+
26
+ if Nokogiri.uses_libxml?
27
+ def reset
28
+ return unless
29
+
30
+ @registered_namespaces.each do |key, _|
31
+ register_ns(key, nil)
32
+ end
33
+ unless @registered_namespaces.empty?
34
+ warn "Nokogiri::XML::XPathContext#reset: unexpected registered namespaces: #{@registered_namespaces.keys}"
35
+ @registered_namespaces.clear
36
+ end
37
+
38
+ @registered_variables.each do |key, _|
39
+ register_variable(key, nil)
40
+ end
41
+ unless @registered_variables.empty?
42
+ warn "Nokogiri::XML::XPathContext#reset: unexpected registered variables: #{@registered_variables.keys}"
43
+ @registered_variables.clear
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nokogiri
4
+ class << self
5
+ # Convenience method for Nokogiri::XML::Document.parse
6
+ def XML(...)
7
+ Nokogiri::XML::Document.parse(...)
8
+ end
9
+ end
10
+
11
+ module XML
12
+ # Original C14N 1.0 spec canonicalization
13
+ XML_C14N_1_0 = 0
14
+ # Exclusive C14N 1.0 spec canonicalization
15
+ XML_C14N_EXCLUSIVE_1_0 = 1
16
+ # C14N 1.1 spec canonicalization
17
+ XML_C14N_1_1 = 2
18
+
19
+ class << self
20
+ # Convenience method for Nokogiri::XML::Reader.new
21
+ def Reader(...)
22
+ Reader.new(...)
23
+ end
24
+
25
+ # Convenience method for Nokogiri::XML::Document.parse
26
+ def parse(...)
27
+ Document.parse(...)
28
+ end
29
+
30
+ # Convenience method for Nokogiri::XML::DocumentFragment.parse
31
+ def fragment(...)
32
+ XML::DocumentFragment.parse(...)
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ require_relative "xml/pp"
39
+ require_relative "xml/parse_options"
40
+ require_relative "xml/sax"
41
+ require_relative "xml/searchable"
42
+ require_relative "xml/node"
43
+ require_relative "xml/attribute_decl"
44
+ require_relative "xml/element_decl"
45
+ require_relative "xml/element_content"
46
+ require_relative "xml/character_data"
47
+ require_relative "xml/namespace"
48
+ require_relative "xml/attr"
49
+ require_relative "xml/dtd"
50
+ require_relative "xml/cdata"
51
+ require_relative "xml/text"
52
+ require_relative "xml/document"
53
+ require_relative "xml/document_fragment"
54
+ require_relative "xml/processing_instruction"
55
+ require_relative "xml/node_set"
56
+ require_relative "xml/syntax_error"
57
+ require_relative "xml/xpath"
58
+ require_relative "xml/xpath_context"
59
+ require_relative "xml/builder"
60
+ require_relative "xml/reader"
61
+ require_relative "xml/notation"
62
+ require_relative "xml/entity_decl"
63
+ require_relative "xml/entity_reference"
64
+ require_relative "xml/schema"
65
+ require_relative "xml/relax_ng"
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nokogiri
4
+ module XSLT
5
+ ###
6
+ # A Stylesheet represents an XSLT Stylesheet object. Stylesheet creation
7
+ # is done through Nokogiri.XSLT. Here is an example of transforming
8
+ # an XML::Document with a Stylesheet:
9
+ #
10
+ # doc = Nokogiri::XML(File.read('some_file.xml'))
11
+ # xslt = Nokogiri::XSLT(File.read('some_transformer.xslt'))
12
+ #
13
+ # xslt.transform(doc) # => Nokogiri::XML::Document
14
+ #
15
+ # Many XSLT transformations include serialization behavior to emit a non-XML document. For these
16
+ # cases, please take care to invoke the #serialize method on the result of the transformation:
17
+ #
18
+ # doc = Nokogiri::XML(File.read('some_file.xml'))
19
+ # xslt = Nokogiri::XSLT(File.read('some_transformer.xslt'))
20
+ # xslt.serialize(xslt.transform(doc)) # => String
21
+ #
22
+ # or use the #apply_to method, which is a shortcut for `serialize(transform(document))`:
23
+ #
24
+ # doc = Nokogiri::XML(File.read('some_file.xml'))
25
+ # xslt = Nokogiri::XSLT(File.read('some_transformer.xslt'))
26
+ # xslt.apply_to(doc) # => String
27
+ #
28
+ # See Nokogiri::XSLT::Stylesheet#transform for more information and examples.
29
+ class Stylesheet
30
+ # :call-seq:
31
+ # apply_to(document, params = []) -> String
32
+ #
33
+ # Apply an XSLT stylesheet to an XML::Document and serialize it properly. This method is
34
+ # equivalent to calling #serialize on the result of #transform.
35
+ #
36
+ # [Parameters]
37
+ # - +document+ is an instance of XML::Document to transform
38
+ # - +params+ is an array of strings used as XSLT parameters, passed into #transform
39
+ #
40
+ # [Returns]
41
+ # A string containing the serialized result of the transformation.
42
+ #
43
+ # See Nokogiri::XSLT::Stylesheet#transform for more information and examples.
44
+ def apply_to(document, params = [])
45
+ serialize(transform(document, params))
46
+ end
47
+ end
48
+ end
49
+ end