libxslt-ruby 1.1.1-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,69 @@
1
+ /* $Id: libxslt.c 42 2007-12-07 06:09:35Z transami $ */
2
+
3
+ /* Please see the LICENSE file for copyright and distribution information */
4
+
5
+ #include "libxslt.h"
6
+ #include "libxml/xmlversion.h"
7
+
8
+ VALUE cXMLDocument;
9
+ VALUE cLibXSLT;
10
+ VALUE cXSLT;
11
+ VALUE eXSLTError;
12
+ VALUE eXMLXSLTStylesheetRequireParsedDoc;
13
+
14
+ /*
15
+ * Document-class: LibXSLT::XSLT
16
+ *
17
+ * The libxslt gem provides Ruby language bindings for GNOME's Libxslt
18
+ * toolkit. It is free software, released under the MIT License.
19
+ *
20
+ * Using the bindings is straightforward:
21
+ *
22
+ * stylesheet_doc = XML::Document.file('stylesheet_file')
23
+ * stylesheet = XSLT::Stylesheet.new(stylesheet_doc)
24
+ *
25
+ * xml_doc = XML::Document.file('xml_file')
26
+ * result = stylesheet.apply(xml_doc)
27
+ *
28
+ */
29
+
30
+ #ifdef RDOC_NEVER_DEFINED
31
+ cLibXSLT = rb_define_module("XSLT");
32
+ #endif
33
+
34
+
35
+ void
36
+ Init_libxslt_ruby(void) {
37
+ LIBXML_TEST_VERSION;
38
+
39
+ cLibXSLT = rb_define_module("LibXSLT");
40
+ cXSLT = rb_define_module_under(cLibXSLT, "XSLT");
41
+
42
+ cXMLDocument = rb_const_get(rb_const_get(rb_const_get(rb_cObject, rb_intern("LibXML")),
43
+ rb_intern("XML")),
44
+ rb_intern("Document"));
45
+
46
+ rb_define_const(cXSLT, "MAX_DEPTH", INT2NUM(xsltMaxDepth));
47
+ rb_define_const(cXSLT, "MAX_SORT", INT2NUM(XSLT_MAX_SORT));
48
+ rb_define_const(cXSLT, "ENGINE_VERSION", rb_str_new2(xsltEngineVersion));
49
+ rb_define_const(cXSLT, "LIBXSLT_VERSION", INT2NUM(xsltLibxsltVersion));
50
+ rb_define_const(cXSLT, "LIBXML_VERSION", INT2NUM(xsltLibxmlVersion));
51
+ rb_define_const(cXSLT, "XSLT_NAMESPACE", rb_str_new2((const char*)XSLT_NAMESPACE));
52
+ rb_define_const(cXSLT, "DEFAULT_VENDOR", rb_str_new2(XSLT_DEFAULT_VENDOR));
53
+ rb_define_const(cXSLT, "DEFAULT_VERSION", rb_str_new2(XSLT_DEFAULT_VERSION));
54
+ rb_define_const(cXSLT, "DEFAULT_URL", rb_str_new2(XSLT_DEFAULT_URL));
55
+ rb_define_const(cXSLT, "NAMESPACE_LIBXSLT", rb_str_new2((const char*)XSLT_LIBXSLT_NAMESPACE));
56
+ rb_define_const(cXSLT, "NAMESPACE_NORM_SAXON", rb_str_new2((const char*)XSLT_NORM_SAXON_NAMESPACE));
57
+ rb_define_const(cXSLT, "NAMESPACE_SAXON", rb_str_new2((const char*)XSLT_SAXON_NAMESPACE));
58
+ rb_define_const(cXSLT, "NAMESPACE_XT", rb_str_new2((const char*)XSLT_XT_NAMESPACE));
59
+ rb_define_const(cXSLT, "NAMESPACE_XALAN", rb_str_new2((const char*)XSLT_XALAN_NAMESPACE));
60
+
61
+ eXSLTError = rb_define_class_under(cLibXSLT, "XSLTError", rb_eRuntimeError);
62
+ eXMLXSLTStylesheetRequireParsedDoc = rb_define_class_under(cLibXSLT, "ResultError", rb_eRuntimeError);
63
+
64
+ ruby_init_xslt_stylesheet();
65
+ ruby_init_exslt();
66
+
67
+ /* Now load exslt. */
68
+ exsltRegisterAll();
69
+ }
@@ -0,0 +1,37 @@
1
+ /* $Id: libxslt.h 43 2007-12-07 12:38:59Z transami $ */
2
+
3
+ /* Please see the LICENSE file for copyright and distribution information */
4
+
5
+ #include <libxml/parser.h>
6
+ #include <libxml/debugXML.h>
7
+
8
+ #ifndef __RUBY_LIBXSLT_H__
9
+ #define __RUBY_LIBXSLT_H__
10
+
11
+ #include <ruby.h>
12
+ #if HAVE_RUBY_IO_H
13
+ #include <ruby/io.h>
14
+ #else
15
+ #include <rubyio.h>
16
+ #endif
17
+
18
+ #include <ruby_libxml.h>
19
+
20
+ #include <libxslt/extra.h>
21
+ #include <libxslt/xslt.h>
22
+ #include <libxslt/xsltInternals.h>
23
+ #include <libxslt/transform.h>
24
+ #include <libxslt/xsltutils.h>
25
+
26
+ #include <libexslt/exslt.h>
27
+
28
+ #include "ruby_xslt_stylesheet.h"
29
+ #include "ruby_exslt.h"
30
+
31
+ #include "version.h"
32
+
33
+ extern VALUE cXSLT;
34
+ extern VALUE eXSLTError;
35
+ extern VALUE eXMLXSLTStylesheetRequireParsedDoc;
36
+
37
+ #endif
@@ -0,0 +1,149 @@
1
+ /* http://xmlsoft.org/XSLT/html/libxslt-extensions.html */
2
+
3
+ #include "libxslt.h"
4
+
5
+ /* Helper method to retrieve (and possibly initialize)
6
+ the module function registry hash for +namespace+ */
7
+ static VALUE
8
+ ruby_xslt_module_function_hash(VALUE namespace) {
9
+ VALUE ns_hash, func_hash;
10
+
11
+ if ((ns_hash = rb_ivar_get(cXSLT, rb_intern("@module_function_registry"))) == Qnil) {
12
+ ns_hash = rb_ivar_set(cXSLT, rb_intern("@module_function_registry"), rb_hash_new());
13
+ }
14
+
15
+ if ((func_hash = rb_hash_aref(ns_hash, namespace)) == Qnil) {
16
+ func_hash = rb_hash_aset(ns_hash, namespace, rb_hash_new());
17
+ }
18
+
19
+ return func_hash;
20
+ }
21
+
22
+ /* Helper method for xsltRegisterExtModuleFunction callback */
23
+ static void
24
+ ruby_xslt_module_function_callback(xmlXPathParserContextPtr ctxt, int nargs) {
25
+ VALUE callback;
26
+ VALUE* args = ALLOCA_N(VALUE, nargs);
27
+ const xmlChar *namespace, *name;
28
+ int i;
29
+
30
+ if (ctxt == NULL || ctxt->context == NULL) {
31
+ return;
32
+ }
33
+
34
+ namespace = ctxt->context->functionURI;
35
+ name = ctxt->context->function;
36
+
37
+ callback = rb_hash_aref(
38
+ ruby_xslt_module_function_hash(rb_str_new2((char *)namespace)),
39
+ rb_str_new2((char *)name)
40
+ );
41
+
42
+ if (callback == Qnil) {
43
+ rb_raise(rb_eArgError, "name `%s' not registered", name);
44
+ }
45
+
46
+ for (i = nargs - 1; i >= 0; i--) {
47
+ args[i] = rxml_xpath_to_value(ctxt->context, valuePop(ctxt));
48
+ }
49
+
50
+ valuePush(ctxt, rxml_xpath_from_value(
51
+ rb_funcall2(callback, rb_intern("call"), nargs, args)
52
+ ));
53
+ }
54
+
55
+ /* call-seq:
56
+ * XSLT.register_module_function(namespace, name) { ... } -> Proc or nil
57
+ *
58
+ * Registers +name+ as extension module function in +namespace+ with the
59
+ * block as callback. Returns the callback if successful, or +nil+ otherwise.
60
+ *
61
+ * The callback will be called with whatever XPath expression you pass
62
+ * into the function converted to a Ruby object. Its return value will
63
+ * be converted to an XPath expression again.
64
+ *
65
+ * Example:
66
+ *
67
+ * # register your extension function
68
+ * XSLT.register_module_function('http://ex.ns', 'ex-func') { |xp|
69
+ * xp.to_a.join('|').upcase
70
+ * }
71
+ *
72
+ * # then use it in your stylesheet
73
+ * <xsl:stylesheet ... xmlns:ex="http://ex.ns">
74
+ * ...
75
+ * <xsl:value-of select="ex:ex-func(.)" />
76
+ * <!-- the current node as upper case string -->
77
+ * </xsl:stylesheet>
78
+ */
79
+ static VALUE
80
+ ruby_xslt_register_module_function(VALUE class, VALUE namespace, VALUE name) {
81
+ VALUE callback;
82
+
83
+ if (!rb_block_given_p()) {
84
+ rb_raise(rb_eArgError, "no block given");
85
+ }
86
+
87
+ if (xsltRegisterExtModuleFunction(
88
+ BAD_CAST StringValuePtr(name),
89
+ BAD_CAST StringValuePtr(namespace),
90
+ ruby_xslt_module_function_callback
91
+ ) != 0) {
92
+ return Qnil;
93
+ }
94
+
95
+ callback = rb_block_proc();
96
+
97
+ rb_hash_aset(ruby_xslt_module_function_hash(namespace), name, callback);
98
+ return callback;
99
+ }
100
+
101
+ /* call-seq:
102
+ * XSLT.unregister_module_function(namespace, name) -> Proc or nil
103
+ *
104
+ * Unregisters +name+ as extension module function in +namespace+.
105
+ * Returns the previous callback if successful, or +nil+ otherwise.
106
+ */
107
+ static VALUE
108
+ ruby_xslt_unregister_module_function(VALUE class, VALUE namespace, VALUE name) {
109
+ VALUE func_hash, callback;
110
+
111
+ func_hash = ruby_xslt_module_function_hash(namespace);
112
+
113
+ if ((callback = rb_hash_aref(func_hash, name)) == Qnil) {
114
+ return Qnil;
115
+ }
116
+
117
+ if (xsltUnregisterExtModuleFunction(
118
+ BAD_CAST StringValuePtr(name),
119
+ BAD_CAST StringValuePtr(namespace)
120
+ ) != 0) {
121
+ return Qnil;
122
+ }
123
+
124
+ rb_hash_aset(func_hash, name, Qnil);
125
+ return callback;
126
+ }
127
+
128
+ /* call-seq:
129
+ * XSLT.registered_module_function?(namespace, name) -> true or false
130
+ *
131
+ * Returns +true+ if +name+ is currently registered as extension module
132
+ * function in +namespace+, or +false+ otherwise.
133
+ */
134
+ static VALUE
135
+ ruby_xslt_registered_module_function_p(VALUE class, VALUE namespace, VALUE name) {
136
+ return RTEST(rb_hash_aref(ruby_xslt_module_function_hash(namespace), name));
137
+ }
138
+
139
+ void
140
+ ruby_init_exslt() {
141
+ /* [HACK] Enclosing classes/modules for RDoc:
142
+ * cLibXSLT = rb_define_module("LibXSLT");
143
+ * cXSLT = rb_define_module_under(cLibXSLT, "XSLT");
144
+ */
145
+
146
+ rb_define_singleton_method(cXSLT, "register_module_function", ruby_xslt_register_module_function, 2);
147
+ rb_define_singleton_method(cXSLT, "unregister_module_function", ruby_xslt_unregister_module_function, 2);
148
+ rb_define_singleton_method(cXSLT, "registered_module_function?", ruby_xslt_registered_module_function_p, 2);
149
+ }
@@ -0,0 +1,8 @@
1
+ #ifndef __RUBY_EXSLT__
2
+ #define __RUBY_EXSLT__
3
+
4
+ #include <libxslt/extensions.h>
5
+
6
+ void ruby_init_exslt(void);
7
+
8
+ #endif
@@ -0,0 +1,302 @@
1
+ /* $Id: ruby_xslt_stylesheet.c 42 2007-12-07 06:09:35Z transami $ */
2
+
3
+ /* See the LICENSE file for copyright and distribution information. */
4
+
5
+ #include "libxslt.h"
6
+ /*
7
+ * Document-class: LibXSLT::XSLT::Stylesheet
8
+ *
9
+ * The XSLT::Stylesheet represents a XSL stylesheet that
10
+ * can be used to transform an XML document. For usage information
11
+ * refer to XSLT::Stylesheet#apply
12
+ *
13
+ */
14
+
15
+ VALUE cXSLTStylesheet;
16
+
17
+ void
18
+ ruby_xslt_stylesheet_free(xsltStylesheetPtr xstylesheet) {
19
+ xsltFreeStylesheet(xstylesheet);
20
+ }
21
+
22
+ static VALUE
23
+ ruby_xslt_stylesheet_alloc(VALUE klass) {
24
+ return Data_Wrap_Struct(cXSLTStylesheet,
25
+ NULL, ruby_xslt_stylesheet_free,
26
+ NULL);
27
+ }
28
+
29
+
30
+ /* call-seq:
31
+ * XSLT::Stylesheet.new(document) -> XSLT::Stylesheet
32
+ *
33
+ * Creates a new XSLT stylesheet based on the specified document.
34
+ * For memory management reasons, a copy of the specified document
35
+ * will be made, so its best to create a single copy of a stylesheet
36
+ * and use it multiple times.
37
+ *
38
+ * stylesheet_doc = XML::Document.file('stylesheet_file')
39
+ * stylesheet = XSLT::Stylesheet.new(stylesheet_doc)
40
+ *
41
+ */
42
+ static VALUE
43
+ ruby_xslt_stylesheet_initialize(VALUE self, VALUE document) {
44
+ xmlDocPtr xdoc;
45
+ xmlDocPtr xcopy;
46
+ xsltStylesheetPtr xstylesheet;
47
+
48
+ if (!rb_obj_is_kind_of(document, cXMLDocument))
49
+ rb_raise(rb_eTypeError, "Must pass in an XML::Document instance.");
50
+
51
+ /* NOTE!! Since the stylesheet own the specified document, the easiest
52
+ * thing to do from a memory standpoint is too copy it and not expose
53
+ * the copy to Ruby. The other solution is expose a memory management
54
+ * API on the document object for taking ownership of the document
55
+ * and specifying when it has been freed. Then the document class
56
+ * has to be updated to always check and see if the document is
57
+ * still valid. That's all doable, but seems like a pain, so
58
+ * just copy the document for now. */
59
+ Data_Get_Struct(document, xmlDoc, xdoc);
60
+ xcopy = xmlCopyDoc(xdoc, 1);
61
+ xstylesheet = xsltParseStylesheetDoc(xcopy);
62
+ xstylesheet->_private = (void *)self;
63
+ DATA_PTR(self) = xstylesheet;
64
+
65
+ /* Save a reference to the document as an attribute accessable to ruby */
66
+ return self;
67
+ }
68
+
69
+ /* Helper method to convert Ruby params to C params */
70
+ char **
71
+ ruby_xslt_coerce_params(VALUE params) {
72
+ char** result;
73
+ size_t length;
74
+ size_t i;
75
+
76
+ length = RARRAY_LEN(params);
77
+ result = ALLOC_N(char *, length + 2);
78
+
79
+ for (i=0; i<length; i++) {
80
+ VALUE str = rb_String(RARRAY_PTR(params)[i]);
81
+ int strLen = RSTRING_LEN(str);
82
+ result[i] = ALLOC_N(char, strLen + 1);
83
+ memset(result[i], 0, strLen + 1);
84
+ strncpy(result[i], RSTRING_PTR(str), strLen);
85
+ }
86
+
87
+ /* Null terminate the array - need to empty elements */
88
+ result[i] = NULL;
89
+ result[i+1] = NULL;
90
+
91
+ return result;
92
+ }
93
+
94
+ /* call-seq:
95
+ * stylesheet.apply(document, {params}) -> XML::Document
96
+ *
97
+ * Apply this stylesheet transformation to the provided document.
98
+ * This method may be invoked multiple times.
99
+ *
100
+ * Params:
101
+ * * document - An instance of an XML::Document
102
+ * * params - An optional hash table that specifies the values for xsl:param values embedded in the stylesheet.
103
+ *
104
+ * Example:
105
+ *
106
+ * stylesheet_doc = XML::Document.file('stylesheet_file')
107
+ * stylesheet = XSLT::Stylesheet.new(stylesheet_doc)
108
+ *
109
+ * xml_doc = XML::Document.file('xml_file')
110
+ * result = stylesheet.apply(xml_doc)
111
+ * result = stylesheet.apply(xml_doc, {:foo => 'bar'})
112
+ */
113
+ static VALUE
114
+ ruby_xslt_stylesheet_apply(int argc, VALUE *argv, VALUE self) {
115
+ xmlDocPtr xdoc;
116
+ xsltStylesheetPtr xstylesheet;
117
+ xmlDocPtr result;
118
+ VALUE document;
119
+ VALUE params;
120
+ int i;
121
+
122
+ char** pParams;
123
+
124
+ if (argc > 2 || argc < 1)
125
+ rb_raise(rb_eArgError, "wrong number of arguments (need 1 or 2)");
126
+
127
+ document = argv[0];
128
+
129
+ if (!rb_obj_is_kind_of(document, cXMLDocument))
130
+ rb_raise(rb_eTypeError, "Must pass in an XML::Document instance.");
131
+
132
+ /* Make sure params is a flat array */
133
+ params = (argc == 2 ? argv[1]: Qnil);
134
+ params = rb_Array(params);
135
+ rb_funcall(params, rb_intern("flatten!"), 0);
136
+ pParams = ruby_xslt_coerce_params(params);
137
+
138
+ Data_Get_Struct(document, xmlDoc, xdoc);
139
+ Data_Get_Struct(self, xsltStylesheet, xstylesheet);
140
+
141
+ result = xsltApplyStylesheet(xstylesheet, xdoc, (const char**)pParams);
142
+
143
+ if (!result)
144
+ rb_raise(eXSLTError, "Transformation failed");
145
+
146
+ /* Free allocated array of *chars. Note we don't have to
147
+ free the last array item since its set to NULL. */
148
+ for (i=0; i<RARRAY_LEN(params); i++) {
149
+ ruby_xfree(pParams[i]);
150
+ }
151
+ ruby_xfree(pParams);
152
+
153
+ return rxml_document_wrap(result);
154
+ }
155
+
156
+
157
+ /* call-seq:
158
+ * sheet.debug(to = $stdout) => (true|false)
159
+ *
160
+ * Output a debug dump of this stylesheet to the specified output
161
+ * stream (an instance of IO, defaults to $stdout). Requires
162
+ * libxml/libxslt be compiled with debugging enabled. If this
163
+ * is not the case, a warning is triggered and the method returns
164
+ * false.
165
+ */
166
+ /*VALUE
167
+ ruby_xslt_stylesheet_debug(int argc, VALUE *argv, VALUE self) {
168
+ #ifdef LIBXML_DEBUG_ENABLED
169
+ OpenFile *fptr;
170
+ VALUE io;
171
+ FILE *out;
172
+ rxml_document_t *parsed;
173
+ ruby_xslt_stylesheet *xss;
174
+
175
+ Data_Get_Struct(self, ruby_xslt_stylesheet, xss);
176
+ if (NIL_P(xss->parsed))
177
+ rb_raise(eXMLXSLTStylesheetRequireParsedDoc, "must have a parsed XML result");
178
+
179
+ switch (argc) {
180
+ case 0:
181
+ io = rb_stdout;
182
+ break;
183
+ case 1:
184
+ io = argv[0];
185
+ if (rb_obj_is_kind_of(io, rb_cIO) == Qfalse)
186
+ rb_raise(rb_eTypeError, "need an IO object");
187
+ break;
188
+ default:
189
+ rb_raise(rb_eArgError, "wrong number of arguments (0 or 1)");
190
+ }
191
+
192
+ Data_Get_Struct(xss->parsed, rxml_document_t, parsed);
193
+ if (parsed->doc == NULL)
194
+ return(Qnil);
195
+
196
+ GetOpenFile(io, fptr);
197
+ rb_io_check_writable(fptr);
198
+ out = GetWriteFile(fptr);
199
+ xmlDebugDumpDocument(out, parsed->doc);
200
+ return(Qtrue);
201
+ #else
202
+ rb_warn("libxml/libxslt was compiled without debugging support. Please recompile libxml/libxslt and their Ruby modules");
203
+ return(Qfalse);
204
+ #endif
205
+ }
206
+ */
207
+
208
+ /* TODO should this automatically apply the sheet if not already,
209
+ given that we're unlikely to do much else with it? */
210
+
211
+ /* call-seq:
212
+ * sheet.print(to = $stdout) => number_of_bytes
213
+ *
214
+ * Output the result of the transform to the specified output
215
+ * stream (an IO instance, defaults to $stdout). You *must* call
216
+ * +apply+ before this method or an exception will be raised.
217
+ */
218
+ /*VALUE
219
+ ruby_xslt_stylesheet_print(int argc, VALUE *argv, VALUE self) {
220
+ OpenFile *fptr;
221
+ VALUE io;
222
+ FILE *out;
223
+ rxml_document_t *parsed;
224
+ ruby_xslt_stylesheet *xss;
225
+ int bytes;
226
+
227
+ Data_Get_Struct(self, ruby_xslt_stylesheet, xss);
228
+ if (NIL_P(xss->parsed))
229
+ rb_raise(eXMLXSLTStylesheetRequireParsedDoc, "must have a parsed XML result");
230
+
231
+ switch (argc) {
232
+ case 0:
233
+ io = rb_stdout;
234
+ break;
235
+ case 1:
236
+ io = argv[0];
237
+ if (rb_obj_is_kind_of(io, rb_cIO) == Qfalse)
238
+ rb_raise(rb_eTypeError, "need an IO object");
239
+ break;
240
+ default:
241
+ rb_raise(rb_eArgError, "wrong number of arguments (0 or 1)");
242
+ }
243
+
244
+ Data_Get_Struct(xss->parsed, rxml_document_t, parsed);
245
+ if (parsed->doc == NULL)
246
+ return(Qnil);
247
+
248
+ GetOpenFile(io, fptr);
249
+ rb_io_check_writable(fptr);
250
+ out = GetWriteFile(fptr);
251
+ bytes = xsltSaveResultToFile(out, parsed->doc, xss->xsp);
252
+
253
+ return(INT2NUM(bytes));
254
+ }*/
255
+
256
+ /* call-seq:
257
+ * stylesheet.output(doc) => string
258
+ *
259
+ * Output an xml document, usually the result of an xslt
260
+ * transformation, and return the result as a string. Output will be
261
+ * done according to the output specification in the xslt
262
+ * stylesheet. Note that this includes the encoding of the string.
263
+ */
264
+ VALUE
265
+ ruby_xslt_stylesheet_output(VALUE self, VALUE document) {
266
+ // FIXME: set string encoding in ruby 1.9?
267
+ xmlDocPtr xdoc;
268
+ xsltStylesheetPtr xstylesheet;
269
+ xmlChar *result = NULL;
270
+ int len = 0, bytes = 0;
271
+ VALUE rresult;
272
+
273
+ if (!rb_obj_is_kind_of(document, cXMLDocument))
274
+ rb_raise(rb_eTypeError, "Must pass in an XML::Document instance.");
275
+
276
+ Data_Get_Struct(document, xmlDoc, xdoc);
277
+ Data_Get_Struct(self, xsltStylesheet, xstylesheet);
278
+
279
+ bytes = xsltSaveResultToString(&result, &len,
280
+ xdoc, xstylesheet);
281
+ if ( bytes == -1 ) {
282
+ rb_raise(rb_eRuntimeError, "error dumping document");
283
+ }
284
+
285
+ rresult=rb_str_new((const char*)result,len);
286
+ xmlFree(result);
287
+ return rresult;
288
+ }
289
+
290
+ #ifdef RDOC_NEVER_DEFINED
291
+ cLibXSLT = rb_define_module("LibXSLT");
292
+ cXSLT = rb_define_module_under(cLibXSLT, "XSLT");
293
+ #endif
294
+
295
+ void
296
+ ruby_init_xslt_stylesheet(void) {
297
+ cXSLTStylesheet = rb_define_class_under(cXSLT, "Stylesheet", rb_cObject);
298
+ rb_define_alloc_func(cXSLTStylesheet, ruby_xslt_stylesheet_alloc);
299
+ rb_define_method(cXSLTStylesheet, "initialize", ruby_xslt_stylesheet_initialize, 1);
300
+ rb_define_method(cXSLTStylesheet, "apply", ruby_xslt_stylesheet_apply, -1);
301
+ rb_define_method(cXSLTStylesheet, "output", ruby_xslt_stylesheet_output, 1);
302
+ }