nokogiri 1.5.10 → 1.13.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.
- checksums.yaml +7 -0
- data/Gemfile +5 -0
- data/LICENSE-DEPENDENCIES.md +1903 -0
- data/LICENSE.md +9 -0
- data/README.md +280 -0
- data/bin/nokogiri +84 -31
- data/dependencies.yml +73 -0
- data/ext/nokogiri/depend +38 -358
- data/ext/nokogiri/extconf.rb +956 -100
- data/ext/nokogiri/gumbo.c +584 -0
- data/ext/nokogiri/html4_document.c +166 -0
- data/ext/nokogiri/html4_element_description.c +294 -0
- data/ext/nokogiri/html4_entity_lookup.c +37 -0
- data/ext/nokogiri/html4_sax_parser_context.c +120 -0
- data/ext/nokogiri/html4_sax_push_parser.c +95 -0
- data/ext/nokogiri/libxml2_backwards_compat.c +121 -0
- data/ext/nokogiri/nokogiri.c +232 -87
- data/ext/nokogiri/nokogiri.h +188 -129
- data/ext/nokogiri/test_global_handlers.c +40 -0
- data/ext/nokogiri/xml_attr.c +49 -40
- data/ext/nokogiri/xml_attribute_decl.c +18 -18
- data/ext/nokogiri/xml_cdata.c +24 -23
- data/ext/nokogiri/xml_comment.c +29 -21
- data/ext/nokogiri/xml_document.c +327 -223
- data/ext/nokogiri/xml_document_fragment.c +12 -16
- data/ext/nokogiri/xml_dtd.c +56 -50
- data/ext/nokogiri/xml_element_content.c +31 -26
- data/ext/nokogiri/xml_element_decl.c +22 -22
- data/ext/nokogiri/xml_encoding_handler.c +45 -20
- data/ext/nokogiri/xml_entity_decl.c +32 -30
- data/ext/nokogiri/xml_entity_reference.c +16 -18
- data/ext/nokogiri/xml_namespace.c +74 -32
- data/ext/nokogiri/xml_node.c +1290 -680
- data/ext/nokogiri/xml_node_set.c +239 -208
- data/ext/nokogiri/xml_processing_instruction.c +17 -19
- data/ext/nokogiri/xml_reader.c +227 -189
- data/ext/nokogiri/xml_relax_ng.c +52 -28
- data/ext/nokogiri/xml_sax_parser.c +123 -125
- data/ext/nokogiri/xml_sax_parser_context.c +138 -79
- data/ext/nokogiri/xml_sax_push_parser.c +88 -35
- data/ext/nokogiri/xml_schema.c +112 -33
- data/ext/nokogiri/xml_syntax_error.c +50 -23
- data/ext/nokogiri/xml_text.c +14 -18
- data/ext/nokogiri/xml_xpath_context.c +227 -140
- data/ext/nokogiri/xslt_stylesheet.c +162 -168
- data/gumbo-parser/CHANGES.md +63 -0
- data/gumbo-parser/Makefile +101 -0
- data/gumbo-parser/THANKS +27 -0
- data/gumbo-parser/src/Makefile +34 -0
- data/gumbo-parser/src/README.md +41 -0
- data/gumbo-parser/src/ascii.c +75 -0
- data/gumbo-parser/src/ascii.h +115 -0
- data/gumbo-parser/src/attribute.c +42 -0
- data/gumbo-parser/src/attribute.h +17 -0
- data/gumbo-parser/src/char_ref.c +22225 -0
- data/gumbo-parser/src/char_ref.h +29 -0
- data/gumbo-parser/src/char_ref.rl +2154 -0
- data/gumbo-parser/src/error.c +626 -0
- data/gumbo-parser/src/error.h +148 -0
- data/gumbo-parser/src/foreign_attrs.c +104 -0
- data/gumbo-parser/src/foreign_attrs.gperf +27 -0
- data/gumbo-parser/src/gumbo.h +943 -0
- data/gumbo-parser/src/insertion_mode.h +33 -0
- data/gumbo-parser/src/macros.h +91 -0
- data/gumbo-parser/src/parser.c +4875 -0
- data/gumbo-parser/src/parser.h +41 -0
- data/gumbo-parser/src/replacement.h +33 -0
- data/gumbo-parser/src/string_buffer.c +103 -0
- data/gumbo-parser/src/string_buffer.h +68 -0
- data/gumbo-parser/src/string_piece.c +48 -0
- data/gumbo-parser/src/svg_attrs.c +174 -0
- data/gumbo-parser/src/svg_attrs.gperf +77 -0
- data/gumbo-parser/src/svg_tags.c +137 -0
- data/gumbo-parser/src/svg_tags.gperf +55 -0
- data/gumbo-parser/src/tag.c +222 -0
- data/gumbo-parser/src/tag_lookup.c +382 -0
- data/gumbo-parser/src/tag_lookup.gperf +169 -0
- data/gumbo-parser/src/tag_lookup.h +13 -0
- data/gumbo-parser/src/token_buffer.c +79 -0
- data/gumbo-parser/src/token_buffer.h +71 -0
- data/gumbo-parser/src/token_type.h +17 -0
- data/gumbo-parser/src/tokenizer.c +3463 -0
- data/gumbo-parser/src/tokenizer.h +112 -0
- data/gumbo-parser/src/tokenizer_states.h +339 -0
- data/gumbo-parser/src/utf8.c +245 -0
- data/gumbo-parser/src/utf8.h +164 -0
- data/gumbo-parser/src/util.c +68 -0
- data/gumbo-parser/src/util.h +30 -0
- data/gumbo-parser/src/vector.c +111 -0
- data/gumbo-parser/src/vector.h +45 -0
- data/lib/nokogiri/class_resolver.rb +67 -0
- data/lib/nokogiri/css/node.rb +10 -58
- data/lib/nokogiri/css/parser.rb +327 -288
- data/lib/nokogiri/css/parser.y +67 -45
- data/lib/nokogiri/css/parser_extras.rb +52 -49
- data/lib/nokogiri/css/syntax_error.rb +3 -1
- data/lib/nokogiri/css/tokenizer.rb +107 -104
- data/lib/nokogiri/css/tokenizer.rex +7 -6
- data/lib/nokogiri/css/xpath_visitor.rb +263 -75
- data/lib/nokogiri/css.rb +50 -17
- data/lib/nokogiri/decorators/slop.rb +17 -8
- data/lib/nokogiri/extension.rb +31 -0
- data/lib/nokogiri/gumbo.rb +15 -0
- data/lib/nokogiri/html.rb +38 -27
- data/lib/nokogiri/{html → html4}/builder.rb +4 -2
- data/lib/nokogiri/html4/document.rb +331 -0
- data/lib/nokogiri/html4/document_fragment.rb +54 -0
- data/lib/nokogiri/{html → html4}/element_description.rb +3 -1
- data/lib/nokogiri/html4/element_description_defaults.rb +578 -0
- data/lib/nokogiri/{html → html4}/entity_lookup.rb +4 -2
- data/lib/nokogiri/{html → html4}/sax/parser.rb +24 -15
- data/lib/nokogiri/html4/sax/parser_context.rb +20 -0
- data/lib/nokogiri/html4/sax/push_parser.rb +37 -0
- data/lib/nokogiri/html4.rb +46 -0
- data/lib/nokogiri/html5/document.rb +88 -0
- data/lib/nokogiri/html5/document_fragment.rb +83 -0
- data/lib/nokogiri/html5/node.rb +96 -0
- data/lib/nokogiri/html5.rb +477 -0
- data/lib/nokogiri/jruby/dependencies.rb +21 -0
- data/lib/nokogiri/syntax_error.rb +2 -0
- data/lib/nokogiri/version/constant.rb +6 -0
- data/lib/nokogiri/version/info.rb +221 -0
- data/lib/nokogiri/version.rb +3 -90
- data/lib/nokogiri/xml/attr.rb +6 -3
- data/lib/nokogiri/xml/attribute_decl.rb +3 -1
- data/lib/nokogiri/xml/builder.rb +96 -54
- data/lib/nokogiri/xml/cdata.rb +3 -1
- data/lib/nokogiri/xml/character_data.rb +2 -0
- data/lib/nokogiri/xml/document.rb +234 -95
- data/lib/nokogiri/xml/document_fragment.rb +86 -36
- data/lib/nokogiri/xml/dtd.rb +16 -4
- data/lib/nokogiri/xml/element_content.rb +2 -0
- data/lib/nokogiri/xml/element_decl.rb +3 -1
- data/lib/nokogiri/xml/entity_decl.rb +4 -2
- data/lib/nokogiri/xml/entity_reference.rb +20 -0
- data/lib/nokogiri/xml/namespace.rb +3 -0
- data/lib/nokogiri/xml/node/save_options.rb +8 -4
- data/lib/nokogiri/xml/node.rb +947 -502
- data/lib/nokogiri/xml/node_set.rb +168 -159
- data/lib/nokogiri/xml/notation.rb +13 -0
- data/lib/nokogiri/xml/parse_options.rb +40 -5
- data/lib/nokogiri/xml/pp/character_data.rb +9 -6
- data/lib/nokogiri/xml/pp/node.rb +25 -26
- data/lib/nokogiri/xml/pp.rb +4 -2
- data/lib/nokogiri/xml/processing_instruction.rb +3 -1
- data/lib/nokogiri/xml/reader.rb +23 -28
- data/lib/nokogiri/xml/relax_ng.rb +8 -2
- data/lib/nokogiri/xml/sax/document.rb +45 -49
- data/lib/nokogiri/xml/sax/parser.rb +43 -41
- data/lib/nokogiri/xml/sax/parser_context.rb +8 -3
- data/lib/nokogiri/xml/sax/push_parser.rb +6 -5
- data/lib/nokogiri/xml/sax.rb +6 -4
- data/lib/nokogiri/xml/schema.rb +19 -9
- data/lib/nokogiri/xml/searchable.rb +259 -0
- data/lib/nokogiri/xml/syntax_error.rb +25 -1
- data/lib/nokogiri/xml/text.rb +2 -0
- data/lib/nokogiri/xml/xpath/syntax_error.rb +4 -2
- data/lib/nokogiri/xml/xpath.rb +15 -4
- data/lib/nokogiri/xml/xpath_context.rb +3 -3
- data/lib/nokogiri/xml.rb +38 -36
- data/lib/nokogiri/xslt/stylesheet.rb +3 -1
- data/lib/nokogiri/xslt.rb +18 -16
- data/lib/nokogiri.rb +69 -69
- data/lib/xsd/xmlparser/nokogiri.rb +26 -24
- data/patches/libxml2/0001-Remove-script-macro-support.patch +40 -0
- data/patches/libxml2/0002-Update-entities-to-remove-handling-of-ssi.patch +44 -0
- data/patches/libxml2/0003-libxml2.la-is-in-top_builddir.patch +25 -0
- data/patches/libxml2/0004-use-glibc-strlen.patch +53 -0
- data/patches/libxml2/0005-avoid-isnan-isinf.patch +81 -0
- data/patches/libxml2/0006-update-automake-files-for-arm64.patch +2511 -0
- data/patches/libxml2/0007-Fix-XPath-recursion-limit.patch +31 -0
- data/patches/libxml2/0008-htmlParseComment-handle-abruptly-closed-comments.patch +61 -0
- data/patches/libxml2/0009-allow-wildcard-namespaces.patch +77 -0
- data/patches/libxslt/0001-update-automake-files-for-arm64.patch +2511 -0
- data/patches/libxslt/0002-Fix-xml2-config-check-in-configure-script.patch +19 -0
- data/ports/archives/libxml2-2.9.12.tar.gz +0 -0
- data/ports/archives/libxslt-1.1.34.tar.gz +0 -0
- metadata +382 -460
- data/.autotest +0 -26
- data/.gemtest +0 -0
- data/CHANGELOG.ja.rdoc +0 -785
- data/CHANGELOG.rdoc +0 -783
- data/C_CODING_STYLE.rdoc +0 -33
- data/Manifest.txt +0 -303
- data/README.ja.rdoc +0 -106
- data/README.rdoc +0 -175
- data/ROADMAP.md +0 -90
- data/Rakefile +0 -228
- data/STANDARD_RESPONSES.md +0 -47
- data/Y_U_NO_GEMSPEC.md +0 -155
- data/build_all +0 -105
- data/ext/nokogiri/html_document.c +0 -170
- data/ext/nokogiri/html_document.h +0 -10
- data/ext/nokogiri/html_element_description.c +0 -279
- data/ext/nokogiri/html_element_description.h +0 -10
- data/ext/nokogiri/html_entity_lookup.c +0 -32
- data/ext/nokogiri/html_entity_lookup.h +0 -8
- data/ext/nokogiri/html_sax_parser_context.c +0 -116
- data/ext/nokogiri/html_sax_parser_context.h +0 -11
- data/ext/nokogiri/html_sax_push_parser.c +0 -87
- data/ext/nokogiri/html_sax_push_parser.h +0 -9
- data/ext/nokogiri/xml_attr.h +0 -9
- data/ext/nokogiri/xml_attribute_decl.h +0 -9
- data/ext/nokogiri/xml_cdata.h +0 -9
- data/ext/nokogiri/xml_comment.h +0 -9
- data/ext/nokogiri/xml_document.h +0 -23
- data/ext/nokogiri/xml_document_fragment.h +0 -10
- data/ext/nokogiri/xml_dtd.h +0 -10
- data/ext/nokogiri/xml_element_content.h +0 -10
- data/ext/nokogiri/xml_element_decl.h +0 -9
- data/ext/nokogiri/xml_encoding_handler.h +0 -8
- data/ext/nokogiri/xml_entity_decl.h +0 -10
- data/ext/nokogiri/xml_entity_reference.h +0 -9
- data/ext/nokogiri/xml_io.c +0 -56
- data/ext/nokogiri/xml_io.h +0 -11
- data/ext/nokogiri/xml_libxml2_hacks.c +0 -112
- data/ext/nokogiri/xml_libxml2_hacks.h +0 -12
- data/ext/nokogiri/xml_namespace.h +0 -13
- data/ext/nokogiri/xml_node.h +0 -13
- data/ext/nokogiri/xml_node_set.h +0 -14
- data/ext/nokogiri/xml_processing_instruction.h +0 -9
- data/ext/nokogiri/xml_reader.h +0 -10
- data/ext/nokogiri/xml_relax_ng.h +0 -9
- data/ext/nokogiri/xml_sax_parser.h +0 -39
- data/ext/nokogiri/xml_sax_parser_context.h +0 -10
- data/ext/nokogiri/xml_sax_push_parser.h +0 -9
- data/ext/nokogiri/xml_schema.h +0 -9
- data/ext/nokogiri/xml_syntax_error.h +0 -13
- data/ext/nokogiri/xml_text.h +0 -9
- data/ext/nokogiri/xml_xpath_context.h +0 -10
- data/ext/nokogiri/xslt_stylesheet.h +0 -14
- data/lib/nokogiri/html/document.rb +0 -254
- data/lib/nokogiri/html/document_fragment.rb +0 -41
- data/lib/nokogiri/html/element_description_defaults.rb +0 -671
- data/lib/nokogiri/html/sax/parser_context.rb +0 -16
- data/lib/nokogiri/html/sax/push_parser.rb +0 -16
- data/tasks/cross_compile.rb +0 -150
- data/tasks/nokogiri.org.rb +0 -24
- data/tasks/test.rb +0 -95
- data/test/css/test_nthiness.rb +0 -159
- data/test/css/test_parser.rb +0 -341
- data/test/css/test_tokenizer.rb +0 -198
- data/test/css/test_xpath_visitor.rb +0 -91
- data/test/decorators/test_slop.rb +0 -16
- data/test/files/2ch.html +0 -108
- data/test/files/address_book.rlx +0 -12
- data/test/files/address_book.xml +0 -10
- data/test/files/bar/bar.xsd +0 -4
- data/test/files/dont_hurt_em_why.xml +0 -422
- data/test/files/encoding.html +0 -82
- data/test/files/encoding.xhtml +0 -84
- data/test/files/exslt.xml +0 -8
- data/test/files/exslt.xslt +0 -35
- data/test/files/foo/foo.xsd +0 -4
- data/test/files/metacharset.html +0 -10
- data/test/files/noencoding.html +0 -47
- data/test/files/po.xml +0 -32
- data/test/files/po.xsd +0 -66
- data/test/files/shift_jis.html +0 -10
- data/test/files/shift_jis.xml +0 -5
- data/test/files/snuggles.xml +0 -3
- data/test/files/staff.dtd +0 -10
- data/test/files/staff.xml +0 -59
- data/test/files/staff.xslt +0 -32
- data/test/files/test_document_url/bar.xml +0 -2
- data/test/files/test_document_url/document.dtd +0 -4
- data/test/files/test_document_url/document.xml +0 -6
- data/test/files/tlm.html +0 -850
- data/test/files/to_be_xincluded.xml +0 -2
- data/test/files/valid_bar.xml +0 -2
- data/test/files/xinclude.xml +0 -4
- data/test/helper.rb +0 -154
- data/test/html/sax/test_parser.rb +0 -141
- data/test/html/sax/test_parser_context.rb +0 -46
- data/test/html/test_builder.rb +0 -164
- data/test/html/test_document.rb +0 -552
- data/test/html/test_document_encoding.rb +0 -138
- data/test/html/test_document_fragment.rb +0 -261
- data/test/html/test_element_description.rb +0 -105
- data/test/html/test_named_characters.rb +0 -14
- data/test/html/test_node.rb +0 -196
- data/test/html/test_node_encoding.rb +0 -27
- data/test/namespaces/test_additional_namespaces_in_builder_doc.rb +0 -14
- data/test/namespaces/test_namespaces_in_builder_doc.rb +0 -75
- data/test/namespaces/test_namespaces_in_created_doc.rb +0 -75
- data/test/namespaces/test_namespaces_in_parsed_doc.rb +0 -66
- data/test/test_convert_xpath.rb +0 -135
- data/test/test_css_cache.rb +0 -45
- data/test/test_encoding_handler.rb +0 -46
- data/test/test_memory_leak.rb +0 -156
- data/test/test_nokogiri.rb +0 -132
- data/test/test_reader.rb +0 -555
- data/test/test_soap4r_sax.rb +0 -52
- data/test/test_xslt_transforms.rb +0 -254
- data/test/xml/node/test_save_options.rb +0 -28
- data/test/xml/node/test_subclass.rb +0 -44
- data/test/xml/sax/test_parser.rb +0 -366
- data/test/xml/sax/test_parser_context.rb +0 -106
- data/test/xml/sax/test_push_parser.rb +0 -157
- data/test/xml/test_attr.rb +0 -64
- data/test/xml/test_attribute_decl.rb +0 -86
- data/test/xml/test_builder.rb +0 -306
- data/test/xml/test_c14n.rb +0 -151
- data/test/xml/test_cdata.rb +0 -48
- data/test/xml/test_comment.rb +0 -29
- data/test/xml/test_document.rb +0 -828
- data/test/xml/test_document_encoding.rb +0 -28
- data/test/xml/test_document_fragment.rb +0 -223
- data/test/xml/test_dtd.rb +0 -103
- data/test/xml/test_dtd_encoding.rb +0 -33
- data/test/xml/test_element_content.rb +0 -56
- data/test/xml/test_element_decl.rb +0 -73
- data/test/xml/test_entity_decl.rb +0 -122
- data/test/xml/test_entity_reference.rb +0 -245
- data/test/xml/test_namespace.rb +0 -95
- data/test/xml/test_node.rb +0 -1137
- data/test/xml/test_node_attributes.rb +0 -96
- data/test/xml/test_node_encoding.rb +0 -107
- data/test/xml/test_node_inheritance.rb +0 -32
- data/test/xml/test_node_reparenting.rb +0 -374
- data/test/xml/test_node_set.rb +0 -755
- data/test/xml/test_parse_options.rb +0 -64
- data/test/xml/test_processing_instruction.rb +0 -30
- data/test/xml/test_reader_encoding.rb +0 -142
- data/test/xml/test_relax_ng.rb +0 -60
- data/test/xml/test_schema.rb +0 -103
- data/test/xml/test_syntax_error.rb +0 -12
- data/test/xml/test_text.rb +0 -45
- data/test/xml/test_unparented_node.rb +0 -422
- data/test/xml/test_xinclude.rb +0 -83
- data/test/xml/test_xpath.rb +0 -295
- data/test/xslt/test_custom_functions.rb +0 -133
- data/test/xslt/test_exception_handling.rb +0 -37
- data/test_all +0 -81
@@ -1,29 +1,127 @@
|
|
1
|
-
#include <
|
1
|
+
#include <nokogiri.h>
|
2
2
|
|
3
|
-
|
3
|
+
VALUE cNokogiriXmlXpathContext;
|
4
|
+
|
5
|
+
/*
|
6
|
+
* these constants have matching declarations in
|
7
|
+
* ext/java/nokogiri/internals/NokogiriNamespaceContext.java
|
8
|
+
*/
|
9
|
+
static const xmlChar *NOKOGIRI_BUILTIN_PREFIX = (const xmlChar *)"nokogiri-builtin";
|
10
|
+
static const xmlChar *NOKOGIRI_BUILTIN_URI = (const xmlChar *)"https://www.nokogiri.org/default_ns/ruby/builtins";
|
4
11
|
|
5
|
-
static void
|
12
|
+
static void
|
13
|
+
deallocate(xmlXPathContextPtr ctx)
|
6
14
|
{
|
7
15
|
NOKOGIRI_DEBUG_START(ctx);
|
8
16
|
xmlXPathFreeContext(ctx);
|
9
17
|
NOKOGIRI_DEBUG_END(ctx);
|
10
18
|
}
|
11
19
|
|
20
|
+
/* find a CSS class in an HTML element's `class` attribute */
|
21
|
+
static const xmlChar *
|
22
|
+
builtin_css_class(const xmlChar *str, const xmlChar *val)
|
23
|
+
{
|
24
|
+
int val_len;
|
25
|
+
|
26
|
+
if (str == NULL) { return (NULL); }
|
27
|
+
if (val == NULL) { return (NULL); }
|
28
|
+
|
29
|
+
val_len = xmlStrlen(val);
|
30
|
+
if (val_len == 0) { return (str); }
|
31
|
+
|
32
|
+
while (*str != 0) {
|
33
|
+
if ((*str == *val) && !xmlStrncmp(str, val, val_len)) {
|
34
|
+
const xmlChar *next_byte = str + val_len;
|
35
|
+
|
36
|
+
/* only match if the next byte is whitespace or end of string */
|
37
|
+
if ((*next_byte == 0) || (IS_BLANK_CH(*next_byte))) {
|
38
|
+
return ((const xmlChar *)str);
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
/* advance str to whitespace */
|
43
|
+
while ((*str != 0) && !IS_BLANK_CH(*str)) {
|
44
|
+
str++;
|
45
|
+
}
|
46
|
+
|
47
|
+
/* advance str to start of next word or end of string */
|
48
|
+
while ((*str != 0) && IS_BLANK_CH(*str)) {
|
49
|
+
str++;
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
return (NULL);
|
54
|
+
}
|
55
|
+
|
56
|
+
/* xmlXPathFunction to wrap builtin_css_class() */
|
57
|
+
static void
|
58
|
+
xpath_builtin_css_class(xmlXPathParserContextPtr ctxt, int nargs)
|
59
|
+
{
|
60
|
+
xmlXPathObjectPtr hay, needle;
|
61
|
+
|
62
|
+
CHECK_ARITY(2);
|
63
|
+
|
64
|
+
CAST_TO_STRING;
|
65
|
+
needle = valuePop(ctxt);
|
66
|
+
if ((needle == NULL) || (needle->type != XPATH_STRING)) {
|
67
|
+
xmlXPathFreeObject(needle);
|
68
|
+
XP_ERROR(XPATH_INVALID_TYPE);
|
69
|
+
}
|
70
|
+
|
71
|
+
CAST_TO_STRING;
|
72
|
+
hay = valuePop(ctxt);
|
73
|
+
if ((hay == NULL) || (hay->type != XPATH_STRING)) {
|
74
|
+
xmlXPathFreeObject(hay);
|
75
|
+
xmlXPathFreeObject(needle);
|
76
|
+
XP_ERROR(XPATH_INVALID_TYPE);
|
77
|
+
}
|
78
|
+
|
79
|
+
if (builtin_css_class(hay->stringval, needle->stringval)) {
|
80
|
+
valuePush(ctxt, xmlXPathNewBoolean(1));
|
81
|
+
} else {
|
82
|
+
valuePush(ctxt, xmlXPathNewBoolean(0));
|
83
|
+
}
|
84
|
+
|
85
|
+
xmlXPathFreeObject(hay);
|
86
|
+
xmlXPathFreeObject(needle);
|
87
|
+
}
|
88
|
+
|
89
|
+
|
90
|
+
/* xmlXPathFunction to select nodes whose local name matches, for HTML5 CSS queries that should ignore namespaces */
|
91
|
+
static void
|
92
|
+
xpath_builtin_local_name_is(xmlXPathParserContextPtr ctxt, int nargs)
|
93
|
+
{
|
94
|
+
xmlXPathObjectPtr element_name;
|
95
|
+
|
96
|
+
assert(ctxt->context->node);
|
97
|
+
|
98
|
+
CHECK_ARITY(1);
|
99
|
+
CAST_TO_STRING;
|
100
|
+
CHECK_TYPE(XPATH_STRING);
|
101
|
+
element_name = valuePop(ctxt);
|
102
|
+
|
103
|
+
valuePush(ctxt, xmlXPathNewBoolean(xmlStrEqual(ctxt->context->node->name, element_name->stringval)));
|
104
|
+
|
105
|
+
xmlXPathFreeObject(element_name);
|
106
|
+
}
|
107
|
+
|
108
|
+
|
12
109
|
/*
|
13
110
|
* call-seq:
|
14
111
|
* register_ns(prefix, uri)
|
15
112
|
*
|
16
113
|
* Register the namespace with +prefix+ and +uri+.
|
17
114
|
*/
|
18
|
-
static VALUE
|
115
|
+
static VALUE
|
116
|
+
register_ns(VALUE self, VALUE prefix, VALUE uri)
|
19
117
|
{
|
20
118
|
xmlXPathContextPtr ctx;
|
21
119
|
Data_Get_Struct(self, xmlXPathContext, ctx);
|
22
120
|
|
23
|
-
xmlXPathRegisterNs(
|
24
|
-
|
25
|
-
|
26
|
-
|
121
|
+
xmlXPathRegisterNs(ctx,
|
122
|
+
(const xmlChar *)StringValueCStr(prefix),
|
123
|
+
(const xmlChar *)StringValueCStr(uri)
|
124
|
+
);
|
27
125
|
return self;
|
28
126
|
}
|
29
127
|
|
@@ -33,74 +131,94 @@ static VALUE register_ns(VALUE self, VALUE prefix, VALUE uri)
|
|
33
131
|
*
|
34
132
|
* Register the variable +name+ with +value+.
|
35
133
|
*/
|
36
|
-
static VALUE
|
134
|
+
static VALUE
|
135
|
+
register_variable(VALUE self, VALUE name, VALUE value)
|
37
136
|
{
|
38
|
-
|
39
|
-
|
40
|
-
|
137
|
+
xmlXPathContextPtr ctx;
|
138
|
+
xmlXPathObjectPtr xmlValue;
|
139
|
+
Data_Get_Struct(self, xmlXPathContext, ctx);
|
41
140
|
|
42
|
-
|
141
|
+
xmlValue = xmlXPathNewCString(StringValueCStr(value));
|
43
142
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
143
|
+
xmlXPathRegisterVariable(ctx,
|
144
|
+
(const xmlChar *)StringValueCStr(name),
|
145
|
+
xmlValue
|
146
|
+
);
|
48
147
|
|
49
|
-
|
148
|
+
return self;
|
50
149
|
}
|
51
150
|
|
52
|
-
|
151
|
+
|
152
|
+
/*
|
153
|
+
* convert an XPath object into a Ruby object of the appropriate type.
|
154
|
+
* returns Qundef if no conversion was possible.
|
155
|
+
*/
|
156
|
+
static VALUE
|
157
|
+
xpath2ruby(xmlXPathObjectPtr xobj, xmlXPathContextPtr xctx)
|
158
|
+
{
|
159
|
+
VALUE retval;
|
160
|
+
|
161
|
+
assert(xctx->doc);
|
162
|
+
assert(DOC_RUBY_OBJECT_TEST(xctx->doc));
|
163
|
+
|
164
|
+
switch (xobj->type) {
|
165
|
+
case XPATH_STRING:
|
166
|
+
retval = NOKOGIRI_STR_NEW2(xobj->stringval);
|
167
|
+
xmlFree(xobj->stringval);
|
168
|
+
return retval;
|
169
|
+
|
170
|
+
case XPATH_NODESET:
|
171
|
+
return noko_xml_node_set_wrap(xobj->nodesetval,
|
172
|
+
DOC_RUBY_OBJECT(xctx->doc));
|
173
|
+
|
174
|
+
case XPATH_NUMBER:
|
175
|
+
return rb_float_new(xobj->floatval);
|
176
|
+
|
177
|
+
case XPATH_BOOLEAN:
|
178
|
+
return (xobj->boolval == 1) ? Qtrue : Qfalse;
|
179
|
+
|
180
|
+
default:
|
181
|
+
return Qundef;
|
182
|
+
}
|
183
|
+
}
|
184
|
+
|
185
|
+
void
|
186
|
+
Nokogiri_marshal_xpath_funcall_and_return_values(xmlXPathParserContextPtr ctx, int nargs, VALUE handler,
|
187
|
+
const char *function_name)
|
53
188
|
{
|
54
|
-
int i;
|
55
189
|
VALUE result, doc;
|
56
190
|
VALUE *argv;
|
57
191
|
VALUE node_set = Qnil;
|
58
192
|
xmlNodeSetPtr xml_node_set = NULL;
|
59
193
|
xmlXPathObjectPtr obj;
|
60
|
-
nokogiriNodeSetTuple *node_set_tuple;
|
61
194
|
|
62
195
|
assert(ctx->context->doc);
|
63
196
|
assert(DOC_RUBY_OBJECT_TEST(ctx->context->doc));
|
64
197
|
|
65
198
|
argv = (VALUE *)calloc((size_t)nargs, sizeof(VALUE));
|
66
|
-
for (
|
67
|
-
rb_gc_register_address(&argv[
|
199
|
+
for (int j = 0 ; j < nargs ; ++j) {
|
200
|
+
rb_gc_register_address(&argv[j]);
|
68
201
|
}
|
69
202
|
|
70
203
|
doc = DOC_RUBY_OBJECT(ctx->context->doc);
|
71
204
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
break;
|
80
|
-
case XPATH_BOOLEAN:
|
81
|
-
argv[i] = obj->boolval == 1 ? Qtrue : Qfalse;
|
82
|
-
break;
|
83
|
-
case XPATH_NUMBER:
|
84
|
-
argv[i] = rb_float_new(obj->floatval);
|
85
|
-
break;
|
86
|
-
case XPATH_NODESET:
|
87
|
-
argv[i] = Nokogiri_wrap_xml_node_set(obj->nodesetval, doc);
|
88
|
-
break;
|
89
|
-
default:
|
90
|
-
argv[i] = NOKOGIRI_STR_NEW2(xmlXPathCastToString(obj));
|
91
|
-
}
|
92
|
-
xmlXPathFreeNodeSetList(obj);
|
93
|
-
} while(i-- > 0);
|
205
|
+
for (int j = nargs - 1 ; j >= 0 ; --j) {
|
206
|
+
obj = valuePop(ctx);
|
207
|
+
argv[j] = xpath2ruby(obj, ctx->context);
|
208
|
+
if (argv[j] == Qundef) {
|
209
|
+
argv[j] = NOKOGIRI_STR_NEW2(xmlXPathCastToString(obj));
|
210
|
+
}
|
211
|
+
xmlXPathFreeNodeSetList(obj);
|
94
212
|
}
|
95
213
|
|
96
|
-
result = rb_funcall2(handler, rb_intern((const char*)function_name), nargs, argv);
|
214
|
+
result = rb_funcall2(handler, rb_intern((const char *)function_name), nargs, argv);
|
97
215
|
|
98
|
-
for (
|
99
|
-
rb_gc_unregister_address(&argv[
|
216
|
+
for (int j = 0 ; j < nargs ; ++j) {
|
217
|
+
rb_gc_unregister_address(&argv[j]);
|
100
218
|
}
|
101
219
|
free(argv);
|
102
220
|
|
103
|
-
switch(TYPE(result)) {
|
221
|
+
switch (TYPE(result)) {
|
104
222
|
case T_FLOAT:
|
105
223
|
case T_BIGNUM:
|
106
224
|
case T_FIXNUM:
|
@@ -108,8 +226,8 @@ void Nokogiri_marshal_xpath_funcall_and_return_values(xmlXPathParserContextPtr c
|
|
108
226
|
break;
|
109
227
|
case T_STRING:
|
110
228
|
xmlXPathReturnString(
|
111
|
-
|
112
|
-
|
229
|
+
ctx,
|
230
|
+
xmlCharStrdup(StringValueCStr(result))
|
113
231
|
);
|
114
232
|
break;
|
115
233
|
case T_TRUE:
|
@@ -120,21 +238,18 @@ void Nokogiri_marshal_xpath_funcall_and_return_values(xmlXPathParserContextPtr c
|
|
120
238
|
break;
|
121
239
|
case T_NIL:
|
122
240
|
break;
|
123
|
-
case T_ARRAY:
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
}
|
133
|
-
break;
|
241
|
+
case T_ARRAY: {
|
242
|
+
VALUE args[2];
|
243
|
+
args[0] = doc;
|
244
|
+
args[1] = result;
|
245
|
+
node_set = rb_class_new_instance(2, args, cNokogiriXmlNodeSet);
|
246
|
+
Data_Get_Struct(node_set, xmlNodeSet, xml_node_set);
|
247
|
+
xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, xml_node_set));
|
248
|
+
}
|
249
|
+
break;
|
134
250
|
case T_DATA:
|
135
|
-
if(rb_obj_is_kind_of(result, cNokogiriXmlNodeSet)) {
|
136
|
-
Data_Get_Struct(result,
|
137
|
-
xml_node_set = node_set_tuple->node_set;
|
251
|
+
if (rb_obj_is_kind_of(result, cNokogiriXmlNodeSet)) {
|
252
|
+
Data_Get_Struct(result, xmlNodeSet, xml_node_set);
|
138
253
|
/* Copy the node set, otherwise it will get GC'd. */
|
139
254
|
xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, xml_node_set));
|
140
255
|
break;
|
@@ -144,7 +259,8 @@ void Nokogiri_marshal_xpath_funcall_and_return_values(xmlXPathParserContextPtr c
|
|
144
259
|
}
|
145
260
|
}
|
146
261
|
|
147
|
-
static void
|
262
|
+
static void
|
263
|
+
ruby_funcall(xmlXPathParserContextPtr ctx, int nargs)
|
148
264
|
{
|
149
265
|
VALUE handler = Qnil;
|
150
266
|
const char *function = NULL ;
|
@@ -155,35 +271,29 @@ static void ruby_funcall(xmlXPathParserContextPtr ctx, int nargs)
|
|
155
271
|
assert(ctx->context->function);
|
156
272
|
|
157
273
|
handler = (VALUE)(ctx->context->userData);
|
158
|
-
function = (const char*)(ctx->context->function);
|
274
|
+
function = (const char *)(ctx->context->function);
|
159
275
|
|
160
276
|
Nokogiri_marshal_xpath_funcall_and_return_values(ctx, nargs, handler, function);
|
161
277
|
}
|
162
278
|
|
163
|
-
static xmlXPathFunction
|
164
|
-
|
165
|
-
|
279
|
+
static xmlXPathFunction
|
280
|
+
lookup(void *ctx,
|
281
|
+
const xmlChar *name,
|
282
|
+
const xmlChar *ns_uri)
|
166
283
|
{
|
167
284
|
VALUE xpath_handler = (VALUE)ctx;
|
168
|
-
if(rb_respond_to(xpath_handler, rb_intern((const char *)name)))
|
285
|
+
if (rb_respond_to(xpath_handler, rb_intern((const char *)name))) {
|
169
286
|
return ruby_funcall;
|
287
|
+
}
|
170
288
|
|
171
289
|
return NULL;
|
172
290
|
}
|
173
291
|
|
174
|
-
NORETURN(static void
|
175
|
-
static void
|
292
|
+
NORETURN(static void xpath_generic_exception_handler(void *ctx, const char *msg, ...));
|
293
|
+
static void
|
294
|
+
xpath_generic_exception_handler(void *ctx, const char *msg, ...)
|
176
295
|
{
|
177
|
-
|
178
|
-
VALUE klass = rb_const_get(xpath, rb_intern("SyntaxError"));
|
179
|
-
|
180
|
-
rb_exc_raise(Nokogiri_wrap_xml_syntax_error(klass, error));
|
181
|
-
}
|
182
|
-
|
183
|
-
NORETURN(static void xpath_generic_exception_handler(void * ctx, const char *msg, ...));
|
184
|
-
static void xpath_generic_exception_handler(void * ctx, const char *msg, ...)
|
185
|
-
{
|
186
|
-
char * message;
|
296
|
+
char *message;
|
187
297
|
|
188
298
|
va_list args;
|
189
299
|
va_start(args, msg);
|
@@ -199,29 +309,31 @@ static void xpath_generic_exception_handler(void * ctx, const char *msg, ...)
|
|
199
309
|
*
|
200
310
|
* Evaluate the +search_path+ returning an XML::XPath object.
|
201
311
|
*/
|
202
|
-
static VALUE
|
312
|
+
static VALUE
|
313
|
+
evaluate(int argc, VALUE *argv, VALUE self)
|
203
314
|
{
|
204
315
|
VALUE search_path, xpath_handler;
|
205
|
-
VALUE
|
316
|
+
VALUE retval = Qnil;
|
206
317
|
xmlXPathContextPtr ctx;
|
207
318
|
xmlXPathObjectPtr xpath;
|
208
319
|
xmlChar *query;
|
209
320
|
|
210
321
|
Data_Get_Struct(self, xmlXPathContext, ctx);
|
211
322
|
|
212
|
-
if(rb_scan_args(argc, argv, "11", &search_path, &xpath_handler) == 1)
|
323
|
+
if (rb_scan_args(argc, argv, "11", &search_path, &xpath_handler) == 1) {
|
213
324
|
xpath_handler = Qnil;
|
325
|
+
}
|
214
326
|
|
215
|
-
query = (xmlChar *)
|
327
|
+
query = (xmlChar *)StringValueCStr(search_path);
|
216
328
|
|
217
|
-
if(Qnil != xpath_handler) {
|
329
|
+
if (Qnil != xpath_handler) {
|
218
330
|
/* FIXME: not sure if this is the correct place to shove private data. */
|
219
331
|
ctx->userData = (void *)xpath_handler;
|
220
332
|
xmlXPathRegisterFuncLookup(ctx, lookup, (void *)xpath_handler);
|
221
333
|
}
|
222
334
|
|
223
335
|
xmlResetLastError();
|
224
|
-
xmlSetStructuredErrorFunc(NULL,
|
336
|
+
xmlSetStructuredErrorFunc(NULL, Nokogiri_error_raise);
|
225
337
|
|
226
338
|
/* For some reason, xmlXPathEvalExpression will blow up with a generic error */
|
227
339
|
/* when there is a non existent function. */
|
@@ -231,45 +343,19 @@ static VALUE evaluate(int argc, VALUE *argv, VALUE self)
|
|
231
343
|
xmlSetStructuredErrorFunc(NULL, NULL);
|
232
344
|
xmlSetGenericErrorFunc(NULL, NULL);
|
233
345
|
|
234
|
-
if(xpath == NULL) {
|
235
|
-
VALUE xpath = rb_const_get(mNokogiriXml, rb_intern("XPath"));
|
236
|
-
VALUE klass = rb_const_get(xpath, rb_intern("SyntaxError"));
|
237
|
-
|
346
|
+
if (xpath == NULL) {
|
238
347
|
xmlErrorPtr error = xmlGetLastError();
|
239
|
-
rb_exc_raise(Nokogiri_wrap_xml_syntax_error(
|
348
|
+
rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
|
240
349
|
}
|
241
350
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
switch(xpath->type) {
|
246
|
-
case XPATH_STRING:
|
247
|
-
thing = NOKOGIRI_STR_NEW2(xpath->stringval);
|
248
|
-
xmlFree(xpath->stringval);
|
249
|
-
break;
|
250
|
-
case XPATH_NODESET:
|
251
|
-
if(NULL == xpath->nodesetval) {
|
252
|
-
thing = Nokogiri_wrap_xml_node_set(xmlXPathNodeSetCreate(NULL),
|
253
|
-
DOC_RUBY_OBJECT(ctx->doc));
|
254
|
-
} else {
|
255
|
-
thing = Nokogiri_wrap_xml_node_set(xpath->nodesetval,
|
256
|
-
DOC_RUBY_OBJECT(ctx->doc));
|
257
|
-
}
|
258
|
-
break;
|
259
|
-
case XPATH_NUMBER:
|
260
|
-
thing = rb_float_new(xpath->floatval);
|
261
|
-
break;
|
262
|
-
case XPATH_BOOLEAN:
|
263
|
-
thing = xpath->boolval == 1 ? Qtrue : Qfalse;
|
264
|
-
break;
|
265
|
-
default:
|
266
|
-
thing = Nokogiri_wrap_xml_node_set(xmlXPathNodeSetCreate(NULL),
|
267
|
-
DOC_RUBY_OBJECT(ctx->doc));
|
351
|
+
retval = xpath2ruby(xpath, ctx);
|
352
|
+
if (retval == Qundef) {
|
353
|
+
retval = noko_xml_node_set_wrap(NULL, DOC_RUBY_OBJECT(ctx->doc));
|
268
354
|
}
|
269
355
|
|
270
356
|
xmlXPathFreeNodeSetList(xpath);
|
271
357
|
|
272
|
-
return
|
358
|
+
return retval;
|
273
359
|
}
|
274
360
|
|
275
361
|
/*
|
@@ -278,42 +364,43 @@ static VALUE evaluate(int argc, VALUE *argv, VALUE self)
|
|
278
364
|
*
|
279
365
|
* Create a new XPathContext with +node+ as the reference point.
|
280
366
|
*/
|
281
|
-
static VALUE
|
367
|
+
static VALUE
|
368
|
+
new (VALUE klass, VALUE nodeobj)
|
282
369
|
{
|
283
370
|
xmlNodePtr node;
|
284
371
|
xmlXPathContextPtr ctx;
|
285
372
|
VALUE self;
|
286
373
|
|
287
|
-
xmlXPathInit();
|
288
|
-
|
289
374
|
Data_Get_Struct(nodeobj, xmlNode, node);
|
290
375
|
|
376
|
+
xmlXPathInit();
|
377
|
+
|
291
378
|
ctx = xmlXPathNewContext(node->doc);
|
292
379
|
ctx->node = node;
|
380
|
+
|
381
|
+
xmlXPathRegisterNs(ctx, NOKOGIRI_BUILTIN_PREFIX, NOKOGIRI_BUILTIN_URI);
|
382
|
+
xmlXPathRegisterFuncNS(ctx, (const xmlChar *)"css-class", NOKOGIRI_BUILTIN_URI,
|
383
|
+
xpath_builtin_css_class);
|
384
|
+
xmlXPathRegisterFuncNS(ctx, (const xmlChar *)"local-name-is", NOKOGIRI_BUILTIN_URI,
|
385
|
+
xpath_builtin_local_name_is);
|
386
|
+
|
293
387
|
self = Data_Wrap_Struct(klass, 0, deallocate, ctx);
|
294
|
-
/*rb_iv_set(self, "@xpath_handler", Qnil); */
|
295
388
|
return self;
|
296
389
|
}
|
297
390
|
|
298
|
-
|
299
|
-
|
391
|
+
void
|
392
|
+
noko_init_xml_xpath_context(void)
|
300
393
|
{
|
301
|
-
VALUE module = rb_define_module("Nokogiri");
|
302
|
-
|
303
|
-
/*
|
304
|
-
* Nokogiri::XML
|
305
|
-
*/
|
306
|
-
VALUE xml = rb_define_module_under(module, "XML");
|
307
|
-
|
308
394
|
/*
|
309
395
|
* XPathContext is the entry point for searching a Document by using XPath.
|
310
396
|
*/
|
311
|
-
|
397
|
+
cNokogiriXmlXpathContext = rb_define_class_under(mNokogiriXml, "XPathContext", rb_cObject);
|
398
|
+
|
399
|
+
rb_undef_alloc_func(cNokogiriXmlXpathContext);
|
312
400
|
|
313
|
-
cNokogiriXmlXpathContext
|
401
|
+
rb_define_singleton_method(cNokogiriXmlXpathContext, "new", new, 1);
|
314
402
|
|
315
|
-
|
316
|
-
rb_define_method(
|
317
|
-
rb_define_method(
|
318
|
-
rb_define_method(klass, "register_ns", register_ns, 2);
|
403
|
+
rb_define_method(cNokogiriXmlXpathContext, "evaluate", evaluate, -1);
|
404
|
+
rb_define_method(cNokogiriXmlXpathContext, "register_variable", register_variable, 2);
|
405
|
+
rb_define_method(cNokogiriXmlXpathContext, "register_ns", register_ns, 2);
|
319
406
|
}
|