tenderlove-nokogiri 0.0.0-x86-mswin32-60
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +6 -0
- data/Manifest.txt +120 -0
- data/README.ja.txt +86 -0
- data/README.txt +87 -0
- data/Rakefile +264 -0
- data/ext/nokogiri/extconf.rb +59 -0
- data/ext/nokogiri/html_document.c +83 -0
- data/ext/nokogiri/html_document.h +10 -0
- data/ext/nokogiri/html_sax_parser.c +32 -0
- data/ext/nokogiri/html_sax_parser.h +11 -0
- data/ext/nokogiri/native.c +40 -0
- data/ext/nokogiri/native.h +51 -0
- data/ext/nokogiri/xml_cdata.c +52 -0
- data/ext/nokogiri/xml_cdata.h +9 -0
- data/ext/nokogiri/xml_document.c +159 -0
- data/ext/nokogiri/xml_document.h +10 -0
- data/ext/nokogiri/xml_dtd.c +117 -0
- data/ext/nokogiri/xml_dtd.h +8 -0
- data/ext/nokogiri/xml_node.c +709 -0
- data/ext/nokogiri/xml_node.h +15 -0
- data/ext/nokogiri/xml_node_set.c +124 -0
- data/ext/nokogiri/xml_node_set.h +9 -0
- data/ext/nokogiri/xml_reader.c +429 -0
- data/ext/nokogiri/xml_reader.h +10 -0
- data/ext/nokogiri/xml_sax_parser.c +174 -0
- data/ext/nokogiri/xml_sax_parser.h +10 -0
- data/ext/nokogiri/xml_syntax_error.c +194 -0
- data/ext/nokogiri/xml_syntax_error.h +11 -0
- data/ext/nokogiri/xml_text.c +29 -0
- data/ext/nokogiri/xml_text.h +9 -0
- data/ext/nokogiri/xml_xpath.c +46 -0
- data/ext/nokogiri/xml_xpath.h +11 -0
- data/ext/nokogiri/xml_xpath_context.c +81 -0
- data/ext/nokogiri/xml_xpath_context.h +9 -0
- data/ext/nokogiri/xslt_stylesheet.c +108 -0
- data/ext/nokogiri/xslt_stylesheet.h +9 -0
- data/lib/nokogiri/css/node.rb +95 -0
- data/lib/nokogiri/css/parser.rb +24 -0
- data/lib/nokogiri/css/parser.y +198 -0
- data/lib/nokogiri/css/tokenizer.rb +9 -0
- data/lib/nokogiri/css/tokenizer.rex +63 -0
- data/lib/nokogiri/css/xpath_visitor.rb +165 -0
- data/lib/nokogiri/css.rb +6 -0
- data/lib/nokogiri/decorators/hpricot/node.rb +58 -0
- data/lib/nokogiri/decorators/hpricot/node_set.rb +14 -0
- data/lib/nokogiri/decorators/hpricot/xpath_visitor.rb +17 -0
- data/lib/nokogiri/decorators/hpricot.rb +3 -0
- data/lib/nokogiri/decorators.rb +1 -0
- data/lib/nokogiri/hpricot.rb +47 -0
- data/lib/nokogiri/html/builder.rb +9 -0
- data/lib/nokogiri/html/document.rb +9 -0
- data/lib/nokogiri/html/sax/parser.rb +21 -0
- data/lib/nokogiri/html.rb +95 -0
- data/lib/nokogiri/version.rb +3 -0
- data/lib/nokogiri/xml/after_handler.rb +18 -0
- data/lib/nokogiri/xml/before_handler.rb +32 -0
- data/lib/nokogiri/xml/builder.rb +79 -0
- data/lib/nokogiri/xml/cdata.rb +9 -0
- data/lib/nokogiri/xml/document.rb +30 -0
- data/lib/nokogiri/xml/dtd.rb +6 -0
- data/lib/nokogiri/xml/node.rb +195 -0
- data/lib/nokogiri/xml/node_set.rb +183 -0
- data/lib/nokogiri/xml/notation.rb +6 -0
- data/lib/nokogiri/xml/reader.rb +14 -0
- data/lib/nokogiri/xml/sax/document.rb +59 -0
- data/lib/nokogiri/xml/sax/parser.rb +33 -0
- data/lib/nokogiri/xml/sax.rb +9 -0
- data/lib/nokogiri/xml/syntax_error.rb +21 -0
- data/lib/nokogiri/xml/text.rb +6 -0
- data/lib/nokogiri/xml/xpath.rb +6 -0
- data/lib/nokogiri/xml/xpath_context.rb +14 -0
- data/lib/nokogiri/xml.rb +67 -0
- data/lib/nokogiri/xslt/stylesheet.rb +6 -0
- data/lib/nokogiri/xslt.rb +11 -0
- data/lib/nokogiri.rb +51 -0
- data/nokogiri.gemspec +34 -0
- data/test/css/test_nthiness.rb +159 -0
- data/test/css/test_parser.rb +224 -0
- data/test/css/test_tokenizer.rb +162 -0
- data/test/css/test_xpath_visitor.rb +54 -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 +70 -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 +7 -0
- data/test/hpricot/test_alter.rb +67 -0
- data/test/hpricot/test_builder.rb +27 -0
- data/test/hpricot/test_parser.rb +423 -0
- data/test/hpricot/test_paths.rb +15 -0
- data/test/hpricot/test_preserved.rb +78 -0
- data/test/hpricot/test_xml.rb +30 -0
- data/test/html/sax/test_parser.rb +27 -0
- data/test/html/test_builder.rb +78 -0
- data/test/html/test_document.rb +86 -0
- data/test/test_convert_xpath.rb +180 -0
- data/test/test_nokogiri.rb +36 -0
- data/test/test_reader.rb +222 -0
- data/test/test_xslt_transforms.rb +29 -0
- data/test/xml/sax/test_parser.rb +93 -0
- data/test/xml/test_builder.rb +16 -0
- data/test/xml/test_cdata.rb +18 -0
- data/test/xml/test_document.rb +171 -0
- data/test/xml/test_dtd.rb +43 -0
- data/test/xml/test_node.rb +223 -0
- data/test/xml/test_node_set.rb +116 -0
- data/test/xml/test_text.rb +13 -0
- metadata +214 -0
@@ -0,0 +1,174 @@
|
|
1
|
+
#define _GNU_SOURCE
|
2
|
+
#include <stdio.h>
|
3
|
+
#include <xml_sax_parser.h>
|
4
|
+
|
5
|
+
/*
|
6
|
+
* call-seq:
|
7
|
+
* parse_memory(data)
|
8
|
+
*
|
9
|
+
* Parse the document stored in +data+
|
10
|
+
*/
|
11
|
+
static VALUE parse_memory(VALUE self, VALUE data)
|
12
|
+
{
|
13
|
+
xmlSAXHandlerPtr handler;
|
14
|
+
Data_Get_Struct(self, xmlSAXHandler, handler);
|
15
|
+
xmlSAXUserParseMemory( handler,
|
16
|
+
(void *)self,
|
17
|
+
StringValuePtr(data),
|
18
|
+
NUM2INT(rb_funcall(data, rb_intern("length"), 0))
|
19
|
+
);
|
20
|
+
return data;
|
21
|
+
}
|
22
|
+
|
23
|
+
static VALUE native_parse_file(VALUE self, VALUE data)
|
24
|
+
{
|
25
|
+
xmlSAXHandlerPtr handler;
|
26
|
+
Data_Get_Struct(self, xmlSAXHandler, handler);
|
27
|
+
xmlSAXUserParseFile( handler,
|
28
|
+
(void *)self,
|
29
|
+
StringValuePtr(data)
|
30
|
+
);
|
31
|
+
return data;
|
32
|
+
}
|
33
|
+
|
34
|
+
static void start_document(void * ctx)
|
35
|
+
{
|
36
|
+
VALUE self = (VALUE)ctx;
|
37
|
+
VALUE doc = rb_funcall(self, rb_intern("document"), 0);
|
38
|
+
rb_funcall(doc, rb_intern("start_document"), 0);
|
39
|
+
}
|
40
|
+
|
41
|
+
static void end_document(void * ctx)
|
42
|
+
{
|
43
|
+
VALUE self = (VALUE)ctx;
|
44
|
+
VALUE doc = rb_funcall(self, rb_intern("document"), 0);
|
45
|
+
rb_funcall(doc, rb_intern("end_document"), 0);
|
46
|
+
}
|
47
|
+
|
48
|
+
static void start_element(void * ctx, const xmlChar *name, const xmlChar **atts)
|
49
|
+
{
|
50
|
+
VALUE self = (VALUE)ctx;
|
51
|
+
VALUE doc = rb_funcall(self, rb_intern("document"), 0);
|
52
|
+
VALUE attributes = rb_ary_new();
|
53
|
+
const xmlChar * attr;
|
54
|
+
int i = 0;
|
55
|
+
if(atts) {
|
56
|
+
while((attr = atts[i]) != NULL) {
|
57
|
+
rb_funcall(attributes, rb_intern("<<"), 1, rb_str_new2((const char *)attr));
|
58
|
+
i++;
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
rb_funcall( doc,
|
63
|
+
rb_intern("start_element"),
|
64
|
+
2,
|
65
|
+
rb_str_new2((const char *)name),
|
66
|
+
attributes
|
67
|
+
);
|
68
|
+
}
|
69
|
+
|
70
|
+
static void end_element(void * ctx, const xmlChar *name)
|
71
|
+
{
|
72
|
+
VALUE self = (VALUE)ctx;
|
73
|
+
VALUE doc = rb_funcall(self, rb_intern("document"), 0);
|
74
|
+
rb_funcall(doc, rb_intern("end_element"), 1, rb_str_new2((const char *)name));
|
75
|
+
}
|
76
|
+
|
77
|
+
static void characters_func(void * ctx, const xmlChar * ch, int len)
|
78
|
+
{
|
79
|
+
VALUE self = (VALUE)ctx;
|
80
|
+
VALUE doc = rb_funcall(self, rb_intern("document"), 0);
|
81
|
+
VALUE str = rb_str_new((const char *)ch, (long)len);
|
82
|
+
rb_funcall(doc, rb_intern("characters"), 1, str);
|
83
|
+
}
|
84
|
+
|
85
|
+
static void comment_func(void * ctx, const xmlChar * value)
|
86
|
+
{
|
87
|
+
VALUE self = (VALUE)ctx;
|
88
|
+
VALUE doc = rb_funcall(self, rb_intern("document"), 0);
|
89
|
+
VALUE str = rb_str_new2((const char *)value);
|
90
|
+
rb_funcall(doc, rb_intern("comment"), 1, str);
|
91
|
+
}
|
92
|
+
|
93
|
+
#ifndef XP_WIN
|
94
|
+
static void warning_func(void * ctx, const char *msg, ...)
|
95
|
+
{
|
96
|
+
VALUE self = (VALUE)ctx;
|
97
|
+
VALUE doc = rb_funcall(self, rb_intern("document"), 0);
|
98
|
+
char * message;
|
99
|
+
|
100
|
+
va_list args;
|
101
|
+
va_start(args, msg);
|
102
|
+
vasprintf(&message, msg, args);
|
103
|
+
va_end(args);
|
104
|
+
|
105
|
+
rb_funcall(doc, rb_intern("warning"), 1, rb_str_new2(message));
|
106
|
+
free(message);
|
107
|
+
}
|
108
|
+
#endif
|
109
|
+
|
110
|
+
#ifndef XP_WIN
|
111
|
+
static void error_func(void * ctx, const char *msg, ...)
|
112
|
+
{
|
113
|
+
VALUE self = (VALUE)ctx;
|
114
|
+
VALUE doc = rb_funcall(self, rb_intern("document"), 0);
|
115
|
+
char * message;
|
116
|
+
|
117
|
+
va_list args;
|
118
|
+
va_start(args, msg);
|
119
|
+
vasprintf(&message, msg, args);
|
120
|
+
va_end(args);
|
121
|
+
|
122
|
+
rb_funcall(doc, rb_intern("error"), 1, rb_str_new2(message));
|
123
|
+
free(message);
|
124
|
+
}
|
125
|
+
#endif
|
126
|
+
|
127
|
+
static void cdata_block(void * ctx, const xmlChar * value, int len)
|
128
|
+
{
|
129
|
+
VALUE self = (VALUE)ctx;
|
130
|
+
VALUE doc = rb_funcall(self, rb_intern("document"), 0);
|
131
|
+
VALUE string = rb_str_new((const char *)value, (long)len);
|
132
|
+
rb_funcall(doc, rb_intern("cdata_block"), 1, string);
|
133
|
+
}
|
134
|
+
|
135
|
+
static void deallocate(xmlSAXHandlerPtr handler)
|
136
|
+
{
|
137
|
+
NOKOGIRI_DEBUG_START(handler);
|
138
|
+
free(handler);
|
139
|
+
NOKOGIRI_DEBUG_END(handler);
|
140
|
+
}
|
141
|
+
|
142
|
+
static VALUE allocate(VALUE klass)
|
143
|
+
{
|
144
|
+
xmlSAXHandlerPtr handler = calloc(1, sizeof(xmlSAXHandler));
|
145
|
+
|
146
|
+
handler->startDocument = start_document;
|
147
|
+
handler->endDocument = end_document;
|
148
|
+
handler->startElement = start_element;
|
149
|
+
handler->endElement = end_element;
|
150
|
+
handler->characters = characters_func;
|
151
|
+
handler->comment = comment_func;
|
152
|
+
#ifndef XP_WIN
|
153
|
+
/*
|
154
|
+
* The va*functions aren't in ming, and I don't want to deal with
|
155
|
+
* it right now.....
|
156
|
+
*
|
157
|
+
*/
|
158
|
+
handler->warning = warning_func;
|
159
|
+
handler->error = error_func;
|
160
|
+
#endif
|
161
|
+
handler->cdataBlock = cdata_block;
|
162
|
+
|
163
|
+
return Data_Wrap_Struct(klass, NULL, deallocate, handler);
|
164
|
+
}
|
165
|
+
|
166
|
+
VALUE cNokogiriXmlSaxParser ;
|
167
|
+
void init_xml_sax_parser()
|
168
|
+
{
|
169
|
+
VALUE klass = cNokogiriXmlSaxParser =
|
170
|
+
rb_const_get(mNokogiriXmlSax, rb_intern("Parser"));
|
171
|
+
rb_define_alloc_func(klass, allocate);
|
172
|
+
rb_define_method(klass, "parse_memory", parse_memory, 1);
|
173
|
+
rb_define_private_method(klass, "native_parse_file", native_parse_file, 1);
|
174
|
+
}
|
@@ -0,0 +1,194 @@
|
|
1
|
+
#include <xml_syntax_error.h>
|
2
|
+
|
3
|
+
static void dealloc(xmlErrorPtr ptr)
|
4
|
+
{
|
5
|
+
NOKOGIRI_DEBUG_START(ptr);
|
6
|
+
free(ptr);
|
7
|
+
NOKOGIRI_DEBUG_END(ptr);
|
8
|
+
}
|
9
|
+
|
10
|
+
/*
|
11
|
+
* call-seq:
|
12
|
+
* column
|
13
|
+
*
|
14
|
+
* Column number or 0 if not available
|
15
|
+
*/
|
16
|
+
static VALUE column(VALUE self)
|
17
|
+
{
|
18
|
+
xmlErrorPtr error;
|
19
|
+
Data_Get_Struct(self, xmlError, error);
|
20
|
+
return INT2NUM(error->int2);
|
21
|
+
}
|
22
|
+
|
23
|
+
/*
|
24
|
+
* call-seq:
|
25
|
+
* int1
|
26
|
+
*
|
27
|
+
* Extra number information
|
28
|
+
*/
|
29
|
+
static VALUE int1(VALUE self)
|
30
|
+
{
|
31
|
+
xmlErrorPtr error;
|
32
|
+
Data_Get_Struct(self, xmlError, error);
|
33
|
+
return INT2NUM(error->int1);
|
34
|
+
}
|
35
|
+
|
36
|
+
/*
|
37
|
+
* call-seq:
|
38
|
+
* str3
|
39
|
+
*
|
40
|
+
* Extra string information
|
41
|
+
*/
|
42
|
+
static VALUE str3(VALUE self)
|
43
|
+
{
|
44
|
+
xmlErrorPtr error;
|
45
|
+
Data_Get_Struct(self, xmlError, error);
|
46
|
+
if(error->str3)
|
47
|
+
return rb_str_new2(error->str3);
|
48
|
+
return Qnil;
|
49
|
+
}
|
50
|
+
|
51
|
+
/*
|
52
|
+
* call-seq:
|
53
|
+
* str2
|
54
|
+
*
|
55
|
+
* Extra string information
|
56
|
+
*/
|
57
|
+
static VALUE str2(VALUE self)
|
58
|
+
{
|
59
|
+
xmlErrorPtr error;
|
60
|
+
Data_Get_Struct(self, xmlError, error);
|
61
|
+
if(error->str2)
|
62
|
+
return rb_str_new2(error->str2);
|
63
|
+
return Qnil;
|
64
|
+
}
|
65
|
+
|
66
|
+
/*
|
67
|
+
* call-seq:
|
68
|
+
* str1
|
69
|
+
*
|
70
|
+
* Extra string information
|
71
|
+
*/
|
72
|
+
static VALUE str1(VALUE self)
|
73
|
+
{
|
74
|
+
xmlErrorPtr error;
|
75
|
+
Data_Get_Struct(self, xmlError, error);
|
76
|
+
if(error->str1)
|
77
|
+
return rb_str_new2(error->str1);
|
78
|
+
return Qnil;
|
79
|
+
}
|
80
|
+
|
81
|
+
/*
|
82
|
+
* call-seq:
|
83
|
+
* line
|
84
|
+
*
|
85
|
+
* Get the line number of the error
|
86
|
+
*/
|
87
|
+
static VALUE line(VALUE self)
|
88
|
+
{
|
89
|
+
xmlErrorPtr error;
|
90
|
+
Data_Get_Struct(self, xmlError, error);
|
91
|
+
return INT2NUM(error->line);
|
92
|
+
}
|
93
|
+
|
94
|
+
/*
|
95
|
+
* call-seq:
|
96
|
+
* file
|
97
|
+
*
|
98
|
+
* Get the filename for the error
|
99
|
+
*/
|
100
|
+
static VALUE file(VALUE self)
|
101
|
+
{
|
102
|
+
xmlErrorPtr error;
|
103
|
+
Data_Get_Struct(self, xmlError, error);
|
104
|
+
if(error->file)
|
105
|
+
return rb_str_new2(error->file);
|
106
|
+
|
107
|
+
return Qnil;
|
108
|
+
}
|
109
|
+
|
110
|
+
/*
|
111
|
+
* call-seq:
|
112
|
+
* level
|
113
|
+
*
|
114
|
+
* Get the error level
|
115
|
+
*/
|
116
|
+
static VALUE level(VALUE self)
|
117
|
+
{
|
118
|
+
xmlErrorPtr error;
|
119
|
+
Data_Get_Struct(self, xmlError, error);
|
120
|
+
return INT2NUM((short)error->level);
|
121
|
+
}
|
122
|
+
|
123
|
+
/*
|
124
|
+
* call-seq:
|
125
|
+
* code
|
126
|
+
*
|
127
|
+
* Get the error code
|
128
|
+
*/
|
129
|
+
static VALUE code(VALUE self)
|
130
|
+
{
|
131
|
+
xmlErrorPtr error;
|
132
|
+
Data_Get_Struct(self, xmlError, error);
|
133
|
+
return INT2NUM(error->code);
|
134
|
+
}
|
135
|
+
|
136
|
+
/*
|
137
|
+
* call-seq:
|
138
|
+
* domain
|
139
|
+
*
|
140
|
+
* Get the part of the library that raised this exception
|
141
|
+
*/
|
142
|
+
static VALUE domain(VALUE self)
|
143
|
+
{
|
144
|
+
xmlErrorPtr error;
|
145
|
+
Data_Get_Struct(self, xmlError, error);
|
146
|
+
return INT2NUM(error->domain);
|
147
|
+
}
|
148
|
+
|
149
|
+
/*
|
150
|
+
* call-seq:
|
151
|
+
* message
|
152
|
+
*
|
153
|
+
* Get the human readable message.
|
154
|
+
*/
|
155
|
+
static VALUE message(VALUE self)
|
156
|
+
{
|
157
|
+
xmlErrorPtr error;
|
158
|
+
Data_Get_Struct(self, xmlError, error);
|
159
|
+
return rb_str_new2(error->message);
|
160
|
+
}
|
161
|
+
|
162
|
+
void Nokogiri_error_handler(void * ctx, xmlErrorPtr error)
|
163
|
+
{
|
164
|
+
// FIXME: I'm interneting this. I *think* the pointer passed in here gets
|
165
|
+
// freed on its own, thats why I copy it.
|
166
|
+
// The files are *in* the computer.
|
167
|
+
xmlErrorPtr ptr = calloc(1, sizeof(xmlError));
|
168
|
+
xmlCopyError(error, ptr);
|
169
|
+
|
170
|
+
VALUE err = Data_Wrap_Struct(cNokogiriXmlSyntaxError, NULL, dealloc, ptr);
|
171
|
+
VALUE block = rb_funcall(mNokogiri, rb_intern("error_handler"), 0);
|
172
|
+
rb_funcall(block, rb_intern("call"), 1, err);
|
173
|
+
}
|
174
|
+
|
175
|
+
VALUE cNokogiriXmlSyntaxError;
|
176
|
+
void init_xml_syntax_error()
|
177
|
+
{
|
178
|
+
VALUE nokogiri = rb_define_module("Nokogiri");
|
179
|
+
VALUE xml = rb_define_module_under(nokogiri, "XML");
|
180
|
+
VALUE klass = rb_define_class_under(xml, "SyntaxError", rb_eSyntaxError);
|
181
|
+
cNokogiriXmlSyntaxError = klass;
|
182
|
+
|
183
|
+
rb_define_method(klass, "message", message, 0);
|
184
|
+
rb_define_method(klass, "domain", domain, 0);
|
185
|
+
rb_define_method(klass, "code", code, 0);
|
186
|
+
rb_define_method(klass, "level", level, 0);
|
187
|
+
rb_define_method(klass, "file", file, 0);
|
188
|
+
rb_define_method(klass, "line", line, 0);
|
189
|
+
rb_define_method(klass, "str1", str1, 0);
|
190
|
+
rb_define_method(klass, "str2", str2, 0);
|
191
|
+
rb_define_method(klass, "str3", str3, 0);
|
192
|
+
rb_define_method(klass, "int1", int1, 0);
|
193
|
+
rb_define_method(klass, "column", column, 0);
|
194
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#include <xml_text.h>
|
2
|
+
|
3
|
+
static void dealloc(xmlNodePtr node)
|
4
|
+
{
|
5
|
+
if (node->doc == NULL) {
|
6
|
+
NOKOGIRI_DEBUG_START_TEXT(node);
|
7
|
+
xmlFreeNode(node);
|
8
|
+
NOKOGIRI_DEBUG_END(node);
|
9
|
+
}
|
10
|
+
}
|
11
|
+
|
12
|
+
static VALUE new(VALUE klass, VALUE string)
|
13
|
+
{
|
14
|
+
xmlNodePtr node = xmlNewText((xmlChar *)StringValuePtr(string));
|
15
|
+
VALUE rb_node = Data_Wrap_Struct(klass, NULL, dealloc, node);
|
16
|
+
node->_private = (void *)rb_node;
|
17
|
+
|
18
|
+
if(rb_block_given_p()) rb_yield(rb_node);
|
19
|
+
|
20
|
+
return rb_node;
|
21
|
+
}
|
22
|
+
|
23
|
+
VALUE cNokogiriXmlText ;
|
24
|
+
void init_xml_text()
|
25
|
+
{
|
26
|
+
VALUE klass = cNokogiriXmlText = rb_const_get(mNokogiriXml, rb_intern("Text"));
|
27
|
+
|
28
|
+
rb_define_singleton_method(klass, "new", new, 1);
|
29
|
+
}
|
@@ -0,0 +1,46 @@
|
|
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
|
+
if (xpath->nodesetval)
|
27
|
+
return Nokogiri_wrap_xml_node_set(xpath->nodesetval);
|
28
|
+
|
29
|
+
return Nokogiri_wrap_xml_node_set(xmlXPathNodeSetCreate(NULL));
|
30
|
+
}
|
31
|
+
|
32
|
+
VALUE cNokogiriXmlXpath;
|
33
|
+
void init_xml_xpath(void)
|
34
|
+
{
|
35
|
+
VALUE module = rb_define_module("Nokogiri");
|
36
|
+
VALUE xml = rb_define_module_under(module, "XML");
|
37
|
+
|
38
|
+
/*
|
39
|
+
* This class wraps an XPath object and should only be instantiated from
|
40
|
+
* XPathContext.
|
41
|
+
*/
|
42
|
+
VALUE klass = rb_define_class_under(xml, "XPath", rb_cObject);
|
43
|
+
|
44
|
+
cNokogiriXmlXpath = klass;
|
45
|
+
rb_define_method(klass, "node_set", node_set, 0);
|
46
|
+
}
|
@@ -0,0 +1,81 @@
|
|
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
|
+
/*
|
29
|
+
* call-seq:
|
30
|
+
* evaluate(search_path)
|
31
|
+
*
|
32
|
+
* Evaluate the +search_path+ returning an XML::XPath object.
|
33
|
+
*/
|
34
|
+
static VALUE evaluate(VALUE self, VALUE search_path)
|
35
|
+
{
|
36
|
+
xmlXPathContextPtr ctx;
|
37
|
+
Data_Get_Struct(self, xmlXPathContext, ctx);
|
38
|
+
|
39
|
+
xmlChar* query = (xmlChar *)StringValuePtr(search_path);
|
40
|
+
xmlXPathObjectPtr xpath = xmlXPathEvalExpression(query, ctx);
|
41
|
+
if(xpath == NULL) {
|
42
|
+
rb_raise(rb_eRuntimeError, "Couldn't evaluate expression '%s'", query);
|
43
|
+
}
|
44
|
+
return Nokogiri_wrap_xml_xpath(xpath);
|
45
|
+
}
|
46
|
+
|
47
|
+
/*
|
48
|
+
* call-seq:
|
49
|
+
* new(node)
|
50
|
+
*
|
51
|
+
* Create a new XPathContext with +node+ as the reference point.
|
52
|
+
*/
|
53
|
+
static VALUE new(VALUE klass, VALUE nodeobj)
|
54
|
+
{
|
55
|
+
xmlXPathInit();
|
56
|
+
|
57
|
+
xmlNodePtr node ;
|
58
|
+
Data_Get_Struct(nodeobj, xmlNode, node);
|
59
|
+
|
60
|
+
xmlXPathContextPtr ctx = xmlXPathNewContext(node->doc);
|
61
|
+
ctx->node = node ;
|
62
|
+
return Data_Wrap_Struct(klass, 0, deallocate, ctx);
|
63
|
+
}
|
64
|
+
|
65
|
+
VALUE cNokogiriXmlXpathContext;
|
66
|
+
void init_xml_xpath_context(void)
|
67
|
+
{
|
68
|
+
VALUE module = rb_define_module("Nokogiri");
|
69
|
+
VALUE xml = rb_define_module_under(module, "XML");
|
70
|
+
|
71
|
+
/*
|
72
|
+
* XPathContext is the entry point for searching a Document by using XPath.
|
73
|
+
*/
|
74
|
+
VALUE klass = rb_define_class_under(xml, "XPathContext", rb_cObject);
|
75
|
+
|
76
|
+
cNokogiriXmlXpathContext = klass;
|
77
|
+
|
78
|
+
rb_define_singleton_method(klass, "new", new, 1);
|
79
|
+
rb_define_method(klass, "evaluate", evaluate, 1);
|
80
|
+
rb_define_method(klass, "register_ns", register_ns, 2);
|
81
|
+
}
|
@@ -0,0 +1,108 @@
|
|
1
|
+
#include <xslt_stylesheet.h>
|
2
|
+
|
3
|
+
#include <libxslt/xsltInternals.h>
|
4
|
+
#include <libxslt/xsltutils.h>
|
5
|
+
#include <libxslt/transform.h>
|
6
|
+
|
7
|
+
static void dealloc(xsltStylesheetPtr doc)
|
8
|
+
{
|
9
|
+
NOKOGIRI_DEBUG_START(doc);
|
10
|
+
xsltFreeStylesheet(doc); // commented out for now.
|
11
|
+
NOKOGIRI_DEBUG_END(doc);
|
12
|
+
}
|
13
|
+
|
14
|
+
/*
|
15
|
+
* call-seq:
|
16
|
+
* parse_stylesheet_doc(document)
|
17
|
+
*
|
18
|
+
* Parse a stylesheet from +document+.
|
19
|
+
*/
|
20
|
+
static VALUE parse_stylesheet_doc(VALUE klass, VALUE xmldocobj)
|
21
|
+
{
|
22
|
+
xmlDocPtr xml ;
|
23
|
+
xsltStylesheetPtr ss ;
|
24
|
+
Data_Get_Struct(xmldocobj, xmlDoc, xml);
|
25
|
+
ss = xsltParseStylesheetDoc(xmlCopyDoc(xml, 1)); /* 1 => recursive */
|
26
|
+
return Data_Wrap_Struct(klass, NULL, dealloc, ss);
|
27
|
+
}
|
28
|
+
|
29
|
+
|
30
|
+
/*
|
31
|
+
* call-seq:
|
32
|
+
* serialize(document)
|
33
|
+
*
|
34
|
+
* Serialize +document+ to an xml string.
|
35
|
+
*/
|
36
|
+
static VALUE serialize(VALUE self, VALUE xmlobj)
|
37
|
+
{
|
38
|
+
xmlDocPtr xml ;
|
39
|
+
xsltStylesheetPtr ss ;
|
40
|
+
xmlChar* doc_ptr ;
|
41
|
+
int doc_len ;
|
42
|
+
VALUE rval ;
|
43
|
+
|
44
|
+
Data_Get_Struct(xmlobj, xmlDoc, xml);
|
45
|
+
Data_Get_Struct(self, xsltStylesheet, ss);
|
46
|
+
xsltSaveResultToString(&doc_ptr, &doc_len, xml, ss);
|
47
|
+
rval = rb_str_new((char*)doc_ptr, doc_len);
|
48
|
+
free(doc_ptr);
|
49
|
+
return rval ;
|
50
|
+
}
|
51
|
+
|
52
|
+
|
53
|
+
/*
|
54
|
+
* call-seq:
|
55
|
+
* apply_to(document, params)
|
56
|
+
*
|
57
|
+
* Apply an XSLT stylesheet to an XML::Document.
|
58
|
+
* +params+ is an array of strings used as XSLT parameters.
|
59
|
+
*/
|
60
|
+
static VALUE apply_to(int argc, VALUE* argv, VALUE self)
|
61
|
+
{
|
62
|
+
VALUE xmldoc, paramobj ;
|
63
|
+
xmlDocPtr xml ;
|
64
|
+
xmlDocPtr result ;
|
65
|
+
xsltStylesheetPtr ss ;
|
66
|
+
const char** params ;
|
67
|
+
int param_len, j ;
|
68
|
+
VALUE resultobj ;
|
69
|
+
|
70
|
+
rb_scan_args(argc, argv, "11", &xmldoc, ¶mobj);
|
71
|
+
if (paramobj == Qnil) { paramobj = rb_ary_new2(0) ; }
|
72
|
+
|
73
|
+
Data_Get_Struct(xmldoc, xmlDoc, xml);
|
74
|
+
Data_Get_Struct(self, xsltStylesheet, ss);
|
75
|
+
|
76
|
+
param_len = RARRAY_LEN(paramobj);
|
77
|
+
params = calloc((size_t)param_len+1, sizeof(char*));
|
78
|
+
for (j = 0 ; j < param_len ; j++) {
|
79
|
+
VALUE entry = rb_ary_entry(paramobj, j);
|
80
|
+
const char * ptr = StringValuePtr(entry);
|
81
|
+
params[j] = ptr;
|
82
|
+
}
|
83
|
+
params[param_len] = 0 ;
|
84
|
+
|
85
|
+
result = xsltApplyStylesheet(ss, xml, params);
|
86
|
+
free(params);
|
87
|
+
resultobj = Nokogiri_wrap_xml_document(0, result) ;
|
88
|
+
return rb_funcall(self, rb_intern("serialize"), 1, resultobj);
|
89
|
+
}
|
90
|
+
|
91
|
+
VALUE cNokogiriXsltStylesheet ;
|
92
|
+
void init_xslt_stylesheet()
|
93
|
+
{
|
94
|
+
/*
|
95
|
+
* HACK. This is so that rdoc will work with this C file.
|
96
|
+
*/
|
97
|
+
/*
|
98
|
+
VALUE nokogiri = rb_define_module("Nokogiri");
|
99
|
+
VALUE xslt = rb_define_module_under(nokogiri, "XSLT");
|
100
|
+
VALUE klass = rb_define_class_under(xslt, "Stylesheet", rb_cObject);
|
101
|
+
*/
|
102
|
+
|
103
|
+
VALUE klass = cNokogiriXsltStylesheet = rb_const_get(mNokogiriXslt, rb_intern("Stylesheet"));
|
104
|
+
|
105
|
+
rb_define_singleton_method(klass, "parse_stylesheet_doc", parse_stylesheet_doc, 1);
|
106
|
+
rb_define_method(klass, "serialize", serialize, 1);
|
107
|
+
rb_define_method(klass, "apply_to", apply_to, -1);
|
108
|
+
}
|