nokogiri 1.3.0-x86-mingw32
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.
- data/.autotest +27 -0
- data/CHANGELOG.ja.rdoc +233 -0
- data/CHANGELOG.rdoc +222 -0
- data/Manifest.txt +247 -0
- data/README.ja.rdoc +103 -0
- data/README.rdoc +117 -0
- data/Rakefile +205 -0
- data/bin/nokogiri +47 -0
- data/ext/nokogiri/extconf.rb +89 -0
- data/ext/nokogiri/html_document.c +183 -0
- data/ext/nokogiri/html_document.h +10 -0
- data/ext/nokogiri/html_element_description.c +272 -0
- data/ext/nokogiri/html_element_description.h +10 -0
- data/ext/nokogiri/html_entity_lookup.c +30 -0
- data/ext/nokogiri/html_entity_lookup.h +8 -0
- data/ext/nokogiri/html_sax_parser.c +57 -0
- data/ext/nokogiri/html_sax_parser.h +11 -0
- data/ext/nokogiri/iconv.dll +0 -0
- data/ext/nokogiri/libexslt.dll +0 -0
- data/ext/nokogiri/libxml2.dll +0 -0
- data/ext/nokogiri/libxslt.dll +0 -0
- data/ext/nokogiri/nokogiri.c +81 -0
- data/ext/nokogiri/nokogiri.h +149 -0
- data/ext/nokogiri/xml_attr.c +92 -0
- data/ext/nokogiri/xml_attr.h +9 -0
- data/ext/nokogiri/xml_cdata.c +53 -0
- data/ext/nokogiri/xml_cdata.h +9 -0
- data/ext/nokogiri/xml_comment.c +51 -0
- data/ext/nokogiri/xml_comment.h +9 -0
- data/ext/nokogiri/xml_document.c +308 -0
- data/ext/nokogiri/xml_document.h +21 -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 +102 -0
- data/ext/nokogiri/xml_dtd.h +8 -0
- data/ext/nokogiri/xml_entity_reference.c +50 -0
- data/ext/nokogiri/xml_entity_reference.h +9 -0
- data/ext/nokogiri/xml_io.c +24 -0
- data/ext/nokogiri/xml_io.h +10 -0
- data/ext/nokogiri/xml_namespace.c +69 -0
- data/ext/nokogiri/xml_namespace.h +12 -0
- data/ext/nokogiri/xml_node.c +928 -0
- data/ext/nokogiri/xml_node.h +14 -0
- data/ext/nokogiri/xml_node_set.c +386 -0
- data/ext/nokogiri/xml_node_set.h +9 -0
- data/ext/nokogiri/xml_processing_instruction.c +54 -0
- data/ext/nokogiri/xml_processing_instruction.h +9 -0
- data/ext/nokogiri/xml_reader.c +572 -0
- data/ext/nokogiri/xml_reader.h +10 -0
- data/ext/nokogiri/xml_relax_ng.c +106 -0
- data/ext/nokogiri/xml_relax_ng.h +9 -0
- data/ext/nokogiri/xml_sax_parser.c +336 -0
- data/ext/nokogiri/xml_sax_parser.h +10 -0
- data/ext/nokogiri/xml_sax_push_parser.c +86 -0
- data/ext/nokogiri/xml_sax_push_parser.h +9 -0
- data/ext/nokogiri/xml_schema.c +107 -0
- data/ext/nokogiri/xml_schema.h +9 -0
- data/ext/nokogiri/xml_syntax_error.c +203 -0
- data/ext/nokogiri/xml_syntax_error.h +12 -0
- data/ext/nokogiri/xml_text.c +47 -0
- data/ext/nokogiri/xml_text.h +9 -0
- data/ext/nokogiri/xml_xpath.c +53 -0
- data/ext/nokogiri/xml_xpath.h +11 -0
- data/ext/nokogiri/xml_xpath_context.c +252 -0
- data/ext/nokogiri/xml_xpath_context.h +9 -0
- data/ext/nokogiri/xslt_stylesheet.c +131 -0
- data/ext/nokogiri/xslt_stylesheet.h +9 -0
- data/ext/nokogiri/zlib1.dll +0 -0
- data/lib/action-nokogiri.rb +36 -0
- data/lib/nokogiri.rb +110 -0
- data/lib/nokogiri/1.8/nokogiri.so +0 -0
- data/lib/nokogiri/1.9/nokogiri.so +0 -0
- data/lib/nokogiri/css.rb +25 -0
- data/lib/nokogiri/css/generated_parser.rb +748 -0
- data/lib/nokogiri/css/generated_tokenizer.rb +144 -0
- data/lib/nokogiri/css/node.rb +107 -0
- data/lib/nokogiri/css/parser.rb +82 -0
- data/lib/nokogiri/css/parser.y +227 -0
- data/lib/nokogiri/css/syntax_error.rb +7 -0
- data/lib/nokogiri/css/tokenizer.rb +11 -0
- data/lib/nokogiri/css/tokenizer.rex +54 -0
- data/lib/nokogiri/css/xpath_visitor.rb +172 -0
- data/lib/nokogiri/decorators.rb +2 -0
- data/lib/nokogiri/decorators/hpricot.rb +3 -0
- data/lib/nokogiri/decorators/hpricot/node.rb +56 -0
- data/lib/nokogiri/decorators/hpricot/node_set.rb +54 -0
- data/lib/nokogiri/decorators/hpricot/xpath_visitor.rb +30 -0
- data/lib/nokogiri/decorators/slop.rb +33 -0
- data/lib/nokogiri/ffi/html/document.rb +37 -0
- data/lib/nokogiri/ffi/html/element_description.rb +85 -0
- data/lib/nokogiri/ffi/html/entity_lookup.rb +16 -0
- data/lib/nokogiri/ffi/html/sax/parser.rb +21 -0
- data/lib/nokogiri/ffi/io_callbacks.rb +32 -0
- data/lib/nokogiri/ffi/libxml.rb +314 -0
- data/lib/nokogiri/ffi/structs/common_node.rb +26 -0
- data/lib/nokogiri/ffi/structs/html_elem_desc.rb +24 -0
- data/lib/nokogiri/ffi/structs/html_entity_desc.rb +13 -0
- data/lib/nokogiri/ffi/structs/xml_alloc.rb +16 -0
- data/lib/nokogiri/ffi/structs/xml_attr.rb +19 -0
- data/lib/nokogiri/ffi/structs/xml_buffer.rb +16 -0
- data/lib/nokogiri/ffi/structs/xml_document.rb +108 -0
- data/lib/nokogiri/ffi/structs/xml_dtd.rb +26 -0
- data/lib/nokogiri/ffi/structs/xml_node.rb +28 -0
- data/lib/nokogiri/ffi/structs/xml_node_set.rb +53 -0
- data/lib/nokogiri/ffi/structs/xml_notation.rb +11 -0
- data/lib/nokogiri/ffi/structs/xml_ns.rb +15 -0
- data/lib/nokogiri/ffi/structs/xml_relax_ng.rb +14 -0
- data/lib/nokogiri/ffi/structs/xml_sax_handler.rb +51 -0
- data/lib/nokogiri/ffi/structs/xml_sax_push_parser_context.rb +14 -0
- data/lib/nokogiri/ffi/structs/xml_schema.rb +13 -0
- data/lib/nokogiri/ffi/structs/xml_syntax_error.rb +31 -0
- data/lib/nokogiri/ffi/structs/xml_text_reader.rb +12 -0
- data/lib/nokogiri/ffi/structs/xml_xpath_context.rb +37 -0
- data/lib/nokogiri/ffi/structs/xml_xpath_object.rb +35 -0
- data/lib/nokogiri/ffi/structs/xml_xpath_parser_context.rb +20 -0
- data/lib/nokogiri/ffi/structs/xslt_stylesheet.rb +13 -0
- data/lib/nokogiri/ffi/xml/attr.rb +41 -0
- data/lib/nokogiri/ffi/xml/cdata.rb +19 -0
- data/lib/nokogiri/ffi/xml/comment.rb +18 -0
- data/lib/nokogiri/ffi/xml/document.rb +107 -0
- data/lib/nokogiri/ffi/xml/document_fragment.rb +26 -0
- data/lib/nokogiri/ffi/xml/dtd.rb +42 -0
- data/lib/nokogiri/ffi/xml/entity_reference.rb +19 -0
- data/lib/nokogiri/ffi/xml/namespace.rb +38 -0
- data/lib/nokogiri/ffi/xml/node.rb +380 -0
- data/lib/nokogiri/ffi/xml/node_set.rb +130 -0
- data/lib/nokogiri/ffi/xml/processing_instruction.rb +20 -0
- data/lib/nokogiri/ffi/xml/reader.rb +217 -0
- data/lib/nokogiri/ffi/xml/relax_ng.rb +51 -0
- data/lib/nokogiri/ffi/xml/sax/parser.rb +148 -0
- data/lib/nokogiri/ffi/xml/sax/push_parser.rb +38 -0
- data/lib/nokogiri/ffi/xml/schema.rb +55 -0
- data/lib/nokogiri/ffi/xml/syntax_error.rb +76 -0
- data/lib/nokogiri/ffi/xml/text.rb +18 -0
- data/lib/nokogiri/ffi/xml/xpath.rb +19 -0
- data/lib/nokogiri/ffi/xml/xpath_context.rb +135 -0
- data/lib/nokogiri/ffi/xslt/stylesheet.rb +47 -0
- data/lib/nokogiri/hpricot.rb +62 -0
- data/lib/nokogiri/html.rb +34 -0
- data/lib/nokogiri/html/builder.rb +35 -0
- data/lib/nokogiri/html/document.rb +71 -0
- data/lib/nokogiri/html/document_fragment.rb +15 -0
- data/lib/nokogiri/html/element_description.rb +23 -0
- data/lib/nokogiri/html/entity_lookup.rb +13 -0
- data/lib/nokogiri/html/sax/parser.rb +47 -0
- data/lib/nokogiri/nokogiri.rb +1 -0
- data/lib/nokogiri/syntax_error.rb +4 -0
- data/lib/nokogiri/version.rb +29 -0
- data/lib/nokogiri/version_warning.rb +11 -0
- data/lib/nokogiri/xml.rb +62 -0
- data/lib/nokogiri/xml/attr.rb +9 -0
- data/lib/nokogiri/xml/builder.rb +254 -0
- data/lib/nokogiri/xml/cdata.rb +11 -0
- data/lib/nokogiri/xml/document.rb +100 -0
- data/lib/nokogiri/xml/document_fragment.rb +49 -0
- data/lib/nokogiri/xml/dtd.rb +11 -0
- data/lib/nokogiri/xml/entity_declaration.rb +11 -0
- data/lib/nokogiri/xml/fragment_handler.rb +55 -0
- data/lib/nokogiri/xml/namespace.rb +7 -0
- data/lib/nokogiri/xml/node.rb +745 -0
- data/lib/nokogiri/xml/node/save_options.rb +42 -0
- data/lib/nokogiri/xml/node_set.rb +238 -0
- data/lib/nokogiri/xml/notation.rb +6 -0
- data/lib/nokogiri/xml/parse_options.rb +80 -0
- data/lib/nokogiri/xml/processing_instruction.rb +8 -0
- data/lib/nokogiri/xml/reader.rb +66 -0
- data/lib/nokogiri/xml/relax_ng.rb +32 -0
- data/lib/nokogiri/xml/sax.rb +3 -0
- data/lib/nokogiri/xml/sax/document.rb +143 -0
- data/lib/nokogiri/xml/sax/parser.rb +101 -0
- data/lib/nokogiri/xml/sax/push_parser.rb +60 -0
- data/lib/nokogiri/xml/schema.rb +65 -0
- data/lib/nokogiri/xml/syntax_error.rb +34 -0
- data/lib/nokogiri/xml/xpath.rb +10 -0
- data/lib/nokogiri/xml/xpath/syntax_error.rb +8 -0
- data/lib/nokogiri/xml/xpath_context.rb +16 -0
- data/lib/nokogiri/xslt.rb +48 -0
- data/lib/nokogiri/xslt/stylesheet.rb +25 -0
- data/lib/xsd/xmlparser/nokogiri.rb +64 -0
- data/tasks/test.rb +161 -0
- data/test/css/test_nthiness.rb +160 -0
- data/test/css/test_parser.rb +277 -0
- data/test/css/test_tokenizer.rb +176 -0
- data/test/css/test_xpath_visitor.rb +76 -0
- data/test/ffi/test_document.rb +35 -0
- data/test/files/address_book.rlx +12 -0
- data/test/files/address_book.xml +10 -0
- data/test/files/dont_hurt_em_why.xml +422 -0
- data/test/files/exslt.xml +8 -0
- data/test/files/exslt.xslt +35 -0
- data/test/files/po.xml +32 -0
- data/test/files/po.xsd +66 -0
- data/test/files/staff.xml +59 -0
- data/test/files/staff.xslt +32 -0
- data/test/files/tlm.html +850 -0
- data/test/helper.rb +123 -0
- data/test/hpricot/files/basic.xhtml +17 -0
- data/test/hpricot/files/boingboing.html +2266 -0
- data/test/hpricot/files/cy0.html +3653 -0
- data/test/hpricot/files/immob.html +400 -0
- data/test/hpricot/files/pace_application.html +1320 -0
- data/test/hpricot/files/tenderlove.html +16 -0
- data/test/hpricot/files/uswebgen.html +220 -0
- data/test/hpricot/files/utf8.html +1054 -0
- data/test/hpricot/files/week9.html +1723 -0
- data/test/hpricot/files/why.xml +19 -0
- data/test/hpricot/load_files.rb +11 -0
- data/test/hpricot/test_alter.rb +68 -0
- data/test/hpricot/test_builder.rb +20 -0
- data/test/hpricot/test_parser.rb +426 -0
- data/test/hpricot/test_paths.rb +15 -0
- data/test/hpricot/test_preserved.rb +77 -0
- data/test/hpricot/test_xml.rb +30 -0
- data/test/html/sax/test_parser.rb +52 -0
- data/test/html/test_builder.rb +156 -0
- data/test/html/test_document.rb +361 -0
- data/test/html/test_document_encoding.rb +46 -0
- data/test/html/test_document_fragment.rb +97 -0
- data/test/html/test_element_description.rb +95 -0
- data/test/html/test_named_characters.rb +14 -0
- data/test/html/test_node.rb +165 -0
- data/test/test_convert_xpath.rb +186 -0
- data/test/test_css_cache.rb +56 -0
- data/test/test_gc.rb +15 -0
- data/test/test_memory_leak.rb +77 -0
- data/test/test_nokogiri.rb +127 -0
- data/test/test_reader.rb +316 -0
- data/test/test_xslt_transforms.rb +131 -0
- data/test/xml/node/test_save_options.rb +20 -0
- data/test/xml/node/test_subclass.rb +44 -0
- data/test/xml/sax/test_parser.rb +169 -0
- data/test/xml/sax/test_push_parser.rb +92 -0
- data/test/xml/test_attr.rb +38 -0
- data/test/xml/test_builder.rb +73 -0
- data/test/xml/test_cdata.rb +38 -0
- data/test/xml/test_comment.rb +23 -0
- data/test/xml/test_document.rb +397 -0
- data/test/xml/test_document_encoding.rb +26 -0
- data/test/xml/test_document_fragment.rb +76 -0
- data/test/xml/test_dtd.rb +42 -0
- data/test/xml/test_dtd_encoding.rb +31 -0
- data/test/xml/test_entity_reference.rb +21 -0
- data/test/xml/test_namespace.rb +43 -0
- data/test/xml/test_node.rb +808 -0
- data/test/xml/test_node_attributes.rb +34 -0
- data/test/xml/test_node_encoding.rb +84 -0
- data/test/xml/test_node_set.rb +368 -0
- data/test/xml/test_parse_options.rb +52 -0
- data/test/xml/test_processing_instruction.rb +30 -0
- data/test/xml/test_reader_encoding.rb +126 -0
- data/test/xml/test_relax_ng.rb +60 -0
- data/test/xml/test_schema.rb +65 -0
- data/test/xml/test_text.rb +18 -0
- data/test/xml/test_unparented_node.rb +381 -0
- data/test/xml/test_xpath.rb +106 -0
- metadata +409 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
#include <xml_xpath.h>
|
2
|
+
|
3
|
+
static void deallocate(xmlXPathObjectPtr xpath)
|
4
|
+
{
|
5
|
+
NOKOGIRI_DEBUG_START(xpath);
|
6
|
+
xmlXPathFreeNodeSetList(xpath); // despite the name, this frees the xpath but not the contained node set
|
7
|
+
NOKOGIRI_DEBUG_END(xpath);
|
8
|
+
}
|
9
|
+
|
10
|
+
VALUE Nokogiri_wrap_xml_xpath(xmlXPathObjectPtr xpath)
|
11
|
+
{
|
12
|
+
return Data_Wrap_Struct(cNokogiriXmlXpath, 0, deallocate, xpath);
|
13
|
+
}
|
14
|
+
|
15
|
+
/*
|
16
|
+
* call-seq:
|
17
|
+
* node_set
|
18
|
+
*
|
19
|
+
* Fetch the node set associated with this xpath context.
|
20
|
+
*/
|
21
|
+
static VALUE node_set(VALUE self)
|
22
|
+
{
|
23
|
+
xmlXPathObjectPtr xpath;
|
24
|
+
Data_Get_Struct(self, xmlXPathObject, xpath);
|
25
|
+
|
26
|
+
VALUE node_set = Qnil;
|
27
|
+
|
28
|
+
if (xpath->nodesetval)
|
29
|
+
node_set = Nokogiri_wrap_xml_node_set(xpath->nodesetval);
|
30
|
+
|
31
|
+
if(Qnil == node_set)
|
32
|
+
node_set = Nokogiri_wrap_xml_node_set(xmlXPathNodeSetCreate(NULL));
|
33
|
+
|
34
|
+
rb_funcall(node_set, rb_intern("document="), 1, rb_iv_get(self, "@document"));
|
35
|
+
|
36
|
+
return node_set;
|
37
|
+
}
|
38
|
+
|
39
|
+
VALUE cNokogiriXmlXpath;
|
40
|
+
void init_xml_xpath(void)
|
41
|
+
{
|
42
|
+
VALUE module = rb_define_module("Nokogiri");
|
43
|
+
VALUE xml = rb_define_module_under(module, "XML");
|
44
|
+
|
45
|
+
/*
|
46
|
+
* This class wraps an XPath object and should only be instantiated from
|
47
|
+
* XPathContext.
|
48
|
+
*/
|
49
|
+
VALUE klass = rb_define_class_under(xml, "XPath", rb_cObject);
|
50
|
+
|
51
|
+
cNokogiriXmlXpath = klass;
|
52
|
+
rb_define_method(klass, "node_set", node_set, 0);
|
53
|
+
}
|
@@ -0,0 +1,252 @@
|
|
1
|
+
#include <xml_xpath_context.h>
|
2
|
+
|
3
|
+
static void deallocate(xmlXPathContextPtr ctx)
|
4
|
+
{
|
5
|
+
NOKOGIRI_DEBUG_START(ctx);
|
6
|
+
xmlXPathFreeContext(ctx);
|
7
|
+
NOKOGIRI_DEBUG_END(ctx);
|
8
|
+
}
|
9
|
+
|
10
|
+
/*
|
11
|
+
* call-seq:
|
12
|
+
* register_ns(prefix, uri)
|
13
|
+
*
|
14
|
+
* Register the namespace with +prefix+ and +uri+.
|
15
|
+
*/
|
16
|
+
static VALUE register_ns(VALUE self, VALUE prefix, VALUE uri)
|
17
|
+
{
|
18
|
+
xmlXPathContextPtr ctx;
|
19
|
+
Data_Get_Struct(self, xmlXPathContext, ctx);
|
20
|
+
|
21
|
+
xmlXPathRegisterNs( ctx,
|
22
|
+
(const xmlChar *)StringValuePtr(prefix),
|
23
|
+
(const xmlChar *)StringValuePtr(uri)
|
24
|
+
);
|
25
|
+
return self;
|
26
|
+
}
|
27
|
+
|
28
|
+
static void ruby_funcall(xmlXPathParserContextPtr ctx, int nargs)
|
29
|
+
{
|
30
|
+
VALUE xpath_handler = Qnil;
|
31
|
+
xmlXPathObjectPtr obj;
|
32
|
+
|
33
|
+
assert(ctx);
|
34
|
+
assert(ctx->context);
|
35
|
+
assert(ctx->context->userData);
|
36
|
+
assert(ctx->context->doc);
|
37
|
+
assert(DOC_RUBY_OBJECT_TEST(ctx->context->doc));
|
38
|
+
|
39
|
+
xpath_handler = (VALUE)(ctx->context->userData);
|
40
|
+
|
41
|
+
VALUE * argv = (VALUE *)calloc((unsigned int)nargs, sizeof(VALUE));
|
42
|
+
VALUE doc = DOC_RUBY_OBJECT(ctx->context->doc);
|
43
|
+
|
44
|
+
int i = nargs - 1;
|
45
|
+
do {
|
46
|
+
obj = valuePop(ctx);
|
47
|
+
switch(obj->type) {
|
48
|
+
case XPATH_STRING:
|
49
|
+
argv[i] = NOKOGIRI_STR_NEW2(obj->stringval, ctx->context->doc->encoding);
|
50
|
+
break;
|
51
|
+
case XPATH_BOOLEAN:
|
52
|
+
argv[i] = obj->boolval == 1 ? Qtrue : Qfalse;
|
53
|
+
break;
|
54
|
+
case XPATH_NUMBER:
|
55
|
+
argv[i] = rb_float_new(obj->floatval);
|
56
|
+
break;
|
57
|
+
case XPATH_NODESET:
|
58
|
+
argv[i] = Nokogiri_wrap_xml_node_set(obj->nodesetval);
|
59
|
+
break;
|
60
|
+
default:
|
61
|
+
argv[i] = NOKOGIRI_STR_NEW2(
|
62
|
+
xmlXPathCastToString(obj), ctx->context->doc->encoding
|
63
|
+
);
|
64
|
+
}
|
65
|
+
xmlXPathFreeNodeSetList(obj);
|
66
|
+
} while(i-- > 0);
|
67
|
+
|
68
|
+
VALUE result = rb_funcall2(
|
69
|
+
xpath_handler,
|
70
|
+
rb_intern((const char *)ctx->context->function),
|
71
|
+
nargs,
|
72
|
+
argv
|
73
|
+
);
|
74
|
+
free(argv);
|
75
|
+
|
76
|
+
VALUE node_set = Qnil;
|
77
|
+
xmlNodeSetPtr xml_node_set = NULL;
|
78
|
+
|
79
|
+
switch(TYPE(result)) {
|
80
|
+
case T_FLOAT:
|
81
|
+
case T_BIGNUM:
|
82
|
+
case T_FIXNUM:
|
83
|
+
xmlXPathReturnNumber(ctx, NUM2DBL(result));
|
84
|
+
break;
|
85
|
+
case T_STRING:
|
86
|
+
xmlXPathReturnString(
|
87
|
+
ctx,
|
88
|
+
(xmlChar *)xmlXPathWrapCString(StringValuePtr(result))
|
89
|
+
);
|
90
|
+
break;
|
91
|
+
case T_TRUE:
|
92
|
+
xmlXPathReturnTrue(ctx);
|
93
|
+
break;
|
94
|
+
case T_FALSE:
|
95
|
+
xmlXPathReturnFalse(ctx);
|
96
|
+
break;
|
97
|
+
case T_NIL:
|
98
|
+
break;
|
99
|
+
case T_ARRAY:
|
100
|
+
node_set = rb_funcall(
|
101
|
+
cNokogiriXmlNodeSet,
|
102
|
+
rb_intern("new"),
|
103
|
+
2,
|
104
|
+
doc,
|
105
|
+
result
|
106
|
+
);
|
107
|
+
Data_Get_Struct(node_set, xmlNodeSet, xml_node_set);
|
108
|
+
xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, xml_node_set));
|
109
|
+
break;
|
110
|
+
case T_DATA:
|
111
|
+
if(rb_funcall(result, rb_intern("is_a?"), 1, cNokogiriXmlNodeSet)) {
|
112
|
+
Data_Get_Struct(result, xmlNodeSet, xml_node_set);
|
113
|
+
// Copy the node set, otherwise it will get GC'd.
|
114
|
+
xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, xml_node_set));
|
115
|
+
break;
|
116
|
+
}
|
117
|
+
default:
|
118
|
+
rb_raise(rb_eRuntimeError, "Invalid return type");
|
119
|
+
}
|
120
|
+
}
|
121
|
+
|
122
|
+
static xmlXPathFunction lookup( void *ctx,
|
123
|
+
const xmlChar * name,
|
124
|
+
const xmlChar* ns_uri )
|
125
|
+
{
|
126
|
+
VALUE xpath_handler = (VALUE)ctx;
|
127
|
+
if(rb_respond_to(xpath_handler, rb_intern((const char *)name)))
|
128
|
+
return ruby_funcall;
|
129
|
+
|
130
|
+
return NULL;
|
131
|
+
}
|
132
|
+
|
133
|
+
static void xpath_exception_handler(void * ctx, xmlErrorPtr error)
|
134
|
+
{
|
135
|
+
VALUE xpath = rb_const_get(mNokogiriXml, rb_intern("XPath"));
|
136
|
+
VALUE klass = rb_const_get(xpath, rb_intern("SyntaxError"));
|
137
|
+
|
138
|
+
rb_funcall(rb_mKernel, rb_intern("raise"), 1,
|
139
|
+
Nokogiri_wrap_xml_syntax_error(klass, error)
|
140
|
+
);
|
141
|
+
}
|
142
|
+
|
143
|
+
static void xpath_generic_exception_handler(void * ctx, const char *msg, ...)
|
144
|
+
{
|
145
|
+
char * message;
|
146
|
+
|
147
|
+
va_list args;
|
148
|
+
va_start(args, msg);
|
149
|
+
vasprintf(&message, msg, args);
|
150
|
+
va_end(args);
|
151
|
+
|
152
|
+
rb_raise(rb_eRuntimeError, message);
|
153
|
+
}
|
154
|
+
|
155
|
+
/*
|
156
|
+
* call-seq:
|
157
|
+
* evaluate(search_path)
|
158
|
+
*
|
159
|
+
* Evaluate the +search_path+ returning an XML::XPath object.
|
160
|
+
*/
|
161
|
+
static VALUE evaluate(int argc, VALUE *argv, VALUE self)
|
162
|
+
{
|
163
|
+
VALUE search_path, xpath_handler;
|
164
|
+
xmlXPathContextPtr ctx;
|
165
|
+
Data_Get_Struct(self, xmlXPathContext, ctx);
|
166
|
+
|
167
|
+
if(rb_scan_args(argc, argv, "11", &search_path, &xpath_handler) == 1)
|
168
|
+
xpath_handler = Qnil;
|
169
|
+
|
170
|
+
xmlChar* query = (xmlChar *)StringValuePtr(search_path);
|
171
|
+
|
172
|
+
if(Qnil != xpath_handler) {
|
173
|
+
// FIXME: not sure if this is the correct place to shove private data.
|
174
|
+
ctx->userData = (void *)xpath_handler;
|
175
|
+
xmlXPathRegisterFuncLookup(ctx, lookup, (void *)xpath_handler);
|
176
|
+
}
|
177
|
+
|
178
|
+
xmlResetLastError();
|
179
|
+
xmlSetStructuredErrorFunc(NULL, xpath_exception_handler);
|
180
|
+
|
181
|
+
// For some reason, xmlXPathEvalExpression will blow up with a generic error
|
182
|
+
// when there is a non existent function.
|
183
|
+
xmlSetGenericErrorFunc(NULL, xpath_generic_exception_handler);
|
184
|
+
|
185
|
+
xmlXPathObjectPtr xpath = xmlXPathEvalExpression(query, ctx);
|
186
|
+
xmlSetStructuredErrorFunc(NULL, NULL);
|
187
|
+
xmlSetGenericErrorFunc(NULL, NULL);
|
188
|
+
|
189
|
+
if(xpath == NULL) {
|
190
|
+
VALUE xpath = rb_const_get(mNokogiriXml, rb_intern("XPath"));
|
191
|
+
VALUE klass = rb_const_get(xpath, rb_intern("SyntaxError"));
|
192
|
+
|
193
|
+
xmlErrorPtr error = xmlGetLastError();
|
194
|
+
rb_funcall(rb_mKernel, rb_intern("raise"), 1,
|
195
|
+
Nokogiri_wrap_xml_syntax_error(klass, error)
|
196
|
+
);
|
197
|
+
}
|
198
|
+
|
199
|
+
VALUE xpath_object = Nokogiri_wrap_xml_xpath(xpath);
|
200
|
+
|
201
|
+
assert(ctx->doc);
|
202
|
+
assert(DOC_RUBY_OBJECT_TEST(ctx->doc));
|
203
|
+
|
204
|
+
rb_funcall( xpath_object,
|
205
|
+
rb_intern("document="),
|
206
|
+
1,
|
207
|
+
DOC_RUBY_OBJECT(ctx->doc)
|
208
|
+
);
|
209
|
+
return xpath_object;
|
210
|
+
}
|
211
|
+
|
212
|
+
/*
|
213
|
+
* call-seq:
|
214
|
+
* new(node)
|
215
|
+
*
|
216
|
+
* Create a new XPathContext with +node+ as the reference point.
|
217
|
+
*/
|
218
|
+
static VALUE new(VALUE klass, VALUE nodeobj)
|
219
|
+
{
|
220
|
+
xmlXPathInit();
|
221
|
+
|
222
|
+
xmlNodePtr node ;
|
223
|
+
Data_Get_Struct(nodeobj, xmlNode, node);
|
224
|
+
|
225
|
+
xmlXPathContextPtr ctx = xmlXPathNewContext(node->doc);
|
226
|
+
ctx->node = node;
|
227
|
+
VALUE self = Data_Wrap_Struct(klass, 0, deallocate, ctx);
|
228
|
+
//rb_iv_set(self, "@xpath_handler", Qnil);
|
229
|
+
return self;
|
230
|
+
}
|
231
|
+
|
232
|
+
VALUE cNokogiriXmlXpathContext;
|
233
|
+
void init_xml_xpath_context(void)
|
234
|
+
{
|
235
|
+
VALUE module = rb_define_module("Nokogiri");
|
236
|
+
|
237
|
+
/*
|
238
|
+
* Nokogiri::XML
|
239
|
+
*/
|
240
|
+
VALUE xml = rb_define_module_under(module, "XML");
|
241
|
+
|
242
|
+
/*
|
243
|
+
* XPathContext is the entry point for searching a Document by using XPath.
|
244
|
+
*/
|
245
|
+
VALUE klass = rb_define_class_under(xml, "XPathContext", rb_cObject);
|
246
|
+
|
247
|
+
cNokogiriXmlXpathContext = klass;
|
248
|
+
|
249
|
+
rb_define_singleton_method(klass, "new", new, 1);
|
250
|
+
rb_define_method(klass, "evaluate", evaluate, -1);
|
251
|
+
rb_define_method(klass, "register_ns", register_ns, 2);
|
252
|
+
}
|
@@ -0,0 +1,131 @@
|
|
1
|
+
#include <xslt_stylesheet.h>
|
2
|
+
|
3
|
+
#include <libxslt/xsltInternals.h>
|
4
|
+
#include <libxslt/xsltutils.h>
|
5
|
+
#include <libxslt/transform.h>
|
6
|
+
#include <libexslt/exslt.h>
|
7
|
+
|
8
|
+
static void dealloc(xsltStylesheetPtr doc)
|
9
|
+
{
|
10
|
+
NOKOGIRI_DEBUG_START(doc);
|
11
|
+
xsltFreeStylesheet(doc); // commented out for now.
|
12
|
+
NOKOGIRI_DEBUG_END(doc);
|
13
|
+
}
|
14
|
+
|
15
|
+
static void xslt_generic_error_handler(void * ctx, const char *msg, ...)
|
16
|
+
{
|
17
|
+
char * message;
|
18
|
+
|
19
|
+
va_list args;
|
20
|
+
va_start(args, msg);
|
21
|
+
vasprintf(&message, msg, args);
|
22
|
+
va_end(args);
|
23
|
+
|
24
|
+
rb_raise(rb_eRuntimeError, message);
|
25
|
+
}
|
26
|
+
|
27
|
+
/*
|
28
|
+
* call-seq:
|
29
|
+
* parse_stylesheet_doc(document)
|
30
|
+
*
|
31
|
+
* Parse a stylesheet from +document+.
|
32
|
+
*/
|
33
|
+
static VALUE parse_stylesheet_doc(VALUE klass, VALUE xmldocobj)
|
34
|
+
{
|
35
|
+
xmlDocPtr xml ;
|
36
|
+
xsltStylesheetPtr ss ;
|
37
|
+
Data_Get_Struct(xmldocobj, xmlDoc, xml);
|
38
|
+
exsltRegisterAll();
|
39
|
+
|
40
|
+
xsltSetGenericErrorFunc(NULL, xslt_generic_error_handler);
|
41
|
+
|
42
|
+
ss = xsltParseStylesheetDoc(xmlCopyDoc(xml, 1)); /* 1 => recursive */
|
43
|
+
|
44
|
+
xsltSetGenericErrorFunc(NULL, NULL);
|
45
|
+
|
46
|
+
return Data_Wrap_Struct(klass, NULL, dealloc, ss);
|
47
|
+
}
|
48
|
+
|
49
|
+
|
50
|
+
/*
|
51
|
+
* call-seq:
|
52
|
+
* serialize(document)
|
53
|
+
*
|
54
|
+
* Serialize +document+ to an xml string.
|
55
|
+
*/
|
56
|
+
static VALUE serialize(VALUE self, VALUE xmlobj)
|
57
|
+
{
|
58
|
+
xmlDocPtr xml ;
|
59
|
+
xsltStylesheetPtr ss ;
|
60
|
+
xmlChar* doc_ptr ;
|
61
|
+
int doc_len ;
|
62
|
+
VALUE rval ;
|
63
|
+
|
64
|
+
Data_Get_Struct(xmlobj, xmlDoc, xml);
|
65
|
+
Data_Get_Struct(self, xsltStylesheet, ss);
|
66
|
+
xsltSaveResultToString(&doc_ptr, &doc_len, xml, ss);
|
67
|
+
rval = NOKOGIRI_STR_NEW(doc_ptr, doc_len, xml->encoding);
|
68
|
+
xmlFree(doc_ptr);
|
69
|
+
return rval ;
|
70
|
+
}
|
71
|
+
|
72
|
+
/*
|
73
|
+
* call-seq:
|
74
|
+
* transform(document, params = [])
|
75
|
+
*
|
76
|
+
* Apply an XSLT stylesheet to an XML::Document.
|
77
|
+
* +params+ is an array of strings used as XSLT parameters.
|
78
|
+
* returns Nokogiri::XML::Document
|
79
|
+
*
|
80
|
+
* Example:
|
81
|
+
*
|
82
|
+
* doc = Nokogiri::XML(File.read(ARGV[0]))
|
83
|
+
* xslt = Nokogiri::XSLT(File.read(ARGV[1]))
|
84
|
+
* puts xslt.transform(doc, ['key', 'value'])
|
85
|
+
*
|
86
|
+
*/
|
87
|
+
static VALUE transform(int argc, VALUE* argv, VALUE self)
|
88
|
+
{
|
89
|
+
VALUE xmldoc, paramobj ;
|
90
|
+
xmlDocPtr xml ;
|
91
|
+
xmlDocPtr result ;
|
92
|
+
xsltStylesheetPtr ss ;
|
93
|
+
const char** params ;
|
94
|
+
int param_len, j ;
|
95
|
+
|
96
|
+
rb_scan_args(argc, argv, "11", &xmldoc, ¶mobj);
|
97
|
+
if (paramobj == Qnil) { paramobj = rb_ary_new2(0) ; }
|
98
|
+
|
99
|
+
Data_Get_Struct(xmldoc, xmlDoc, xml);
|
100
|
+
Data_Get_Struct(self, xsltStylesheet, ss);
|
101
|
+
|
102
|
+
param_len = NUM2INT(rb_funcall(paramobj, rb_intern("length"), 0));
|
103
|
+
params = calloc((size_t)param_len+1, sizeof(char*));
|
104
|
+
for (j = 0 ; j < param_len ; j++) {
|
105
|
+
VALUE entry = rb_ary_entry(paramobj, j);
|
106
|
+
const char * ptr = StringValuePtr(entry);
|
107
|
+
params[j] = ptr;
|
108
|
+
}
|
109
|
+
params[param_len] = 0 ;
|
110
|
+
|
111
|
+
result = xsltApplyStylesheet(ss, xml, params);
|
112
|
+
free(params);
|
113
|
+
|
114
|
+
if (!result) rb_raise(rb_eRuntimeError, "could not perform xslt transform on document");
|
115
|
+
|
116
|
+
return Nokogiri_wrap_xml_document(0, result) ;
|
117
|
+
}
|
118
|
+
|
119
|
+
VALUE cNokogiriXsltStylesheet ;
|
120
|
+
void init_xslt_stylesheet()
|
121
|
+
{
|
122
|
+
VALUE nokogiri = rb_define_module("Nokogiri");
|
123
|
+
VALUE xslt = rb_define_module_under(nokogiri, "XSLT");
|
124
|
+
VALUE klass = rb_define_class_under(xslt, "Stylesheet", rb_cObject);
|
125
|
+
|
126
|
+
cNokogiriXsltStylesheet = klass;
|
127
|
+
|
128
|
+
rb_define_singleton_method(klass, "parse_stylesheet_doc", parse_stylesheet_doc, 1);
|
129
|
+
rb_define_method(klass, "serialize", serialize, 1);
|
130
|
+
rb_define_method(klass, "transform", transform, -1);
|
131
|
+
}
|