ruby-xslt 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/xslt.c ADDED
@@ -0,0 +1,619 @@
1
+ /**
2
+ * Copyright (C) 2005 Gregoire Lejeune <gregoire.lejeune@free.fr>
3
+ *
4
+ * This program is free software; you can redistribute it and/or modify
5
+ * it under the terms of the GNU General Public License as published by
6
+ * the Free Software Foundation; either version 2 of the License, or
7
+ * (at your option) any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ * GNU General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+ */
18
+
19
+ #include "xslt.h"
20
+
21
+ VALUE mXML;
22
+ VALUE cXSLT;
23
+ VALUE eXSLTError;
24
+ VALUE eXSLTParsingError;
25
+ VALUE eXSLTTransformationError;
26
+
27
+ void ruby_xslt_free( RbTxslt *pRbTxslt ) {
28
+ if( pRbTxslt != NULL ) {
29
+ if( pRbTxslt->tParsedXslt != NULL )
30
+ xsltFreeStylesheet(pRbTxslt->tParsedXslt);
31
+
32
+ if( pRbTxslt->tXMLDocument != NULL )
33
+ xmlFreeDoc(pRbTxslt->tXMLDocument);
34
+
35
+ free( pRbTxslt );
36
+ }
37
+
38
+ /* xsltCleanupGlobals(); */
39
+ xmlCleanupParser();
40
+ xmlMemoryDump();
41
+ }
42
+
43
+ void ruby_xslt_mark( RbTxslt *pRbTxslt ) {
44
+ if( pRbTxslt == NULL ) return;
45
+ if( !NIL_P(pRbTxslt->xXmlData) ) rb_gc_mark( pRbTxslt->xXmlData );
46
+ if( !NIL_P(pRbTxslt->oXmlObject) ) rb_gc_mark( pRbTxslt->oXmlObject );
47
+ if( !NIL_P(pRbTxslt->xXmlString) ) rb_gc_mark( pRbTxslt->xXmlString );
48
+
49
+ if( !NIL_P(pRbTxslt->xXslData) ) rb_gc_mark( pRbTxslt->xXslData );
50
+ if( !NIL_P(pRbTxslt->oXslObject) ) rb_gc_mark( pRbTxslt->oXslObject );
51
+ if( !NIL_P(pRbTxslt->xXslString) ) rb_gc_mark( pRbTxslt->xXslString );
52
+
53
+ if( !NIL_P(pRbTxslt->xXmlResultCache) ) rb_gc_mark( pRbTxslt->xXmlResultCache );
54
+
55
+ if( !NIL_P(pRbTxslt->pxParams) ) rb_gc_mark( pRbTxslt->pxParams );
56
+ }
57
+
58
+ /**
59
+ * oXSLT = XML::XSLT::new()
60
+ *
61
+ * Create a new XML::XSLT object
62
+ */
63
+ VALUE ruby_xslt_new( VALUE class ) {
64
+ RbTxslt *pRbTxslt;
65
+
66
+ pRbTxslt = (RbTxslt *)malloc(sizeof(RbTxslt));
67
+ if( pRbTxslt == NULL )
68
+ rb_raise(rb_eNoMemError, "No memory left for XSLT struct");
69
+
70
+ pRbTxslt->iXmlType = RUBY_XSLT_XMLSRC_TYPE_NULL;
71
+ pRbTxslt->xXmlData = Qnil;
72
+ pRbTxslt->oXmlObject = Qnil;
73
+ pRbTxslt->xXmlString = Qnil;
74
+ pRbTxslt->tXMLDocument = NULL;
75
+
76
+ pRbTxslt->iXslType = RUBY_XSLT_XSLSRC_TYPE_NULL;
77
+ pRbTxslt->xXslData = Qnil;
78
+ pRbTxslt->oXslObject = Qnil;
79
+ pRbTxslt->xXslString = Qnil;
80
+ pRbTxslt->tParsedXslt = NULL;
81
+
82
+ pRbTxslt->iXmlResultType = RUBY_XSLT_XMLSRC_TYPE_NULL;
83
+ pRbTxslt->xXmlResultCache = Qnil;
84
+
85
+ pRbTxslt->pxParams = Qnil;
86
+ pRbTxslt->iNbParams = 0;
87
+
88
+ xmlInitMemory();
89
+ xmlSubstituteEntitiesDefault( 1 );
90
+ xmlLoadExtDtdDefaultValue = 1;
91
+
92
+ return( Data_Wrap_Struct( class, ruby_xslt_mark, ruby_xslt_free, pRbTxslt ) );
93
+ }
94
+
95
+ /**
96
+ * ----------------------------------------------------------------------------
97
+ */
98
+
99
+ /**
100
+ * oXSLT.xml=<data|REXML::Document|XML::Smart|file>
101
+ *
102
+ * Set XML data.
103
+ *
104
+ * Parameter can be type String, REXML::Document, XML::Smart::Dom or Filename
105
+ *
106
+ * Examples :
107
+ * # Parameter as String
108
+ * oXSLT.xml = <<XML
109
+ * <?xml version="1.0" encoding="UTF-8"?>
110
+ * <test>This is a test string</test>
111
+ * XML
112
+ *
113
+ * # Parameter as REXML::Document
114
+ * require 'rexml/document'
115
+ * oXSLT.xml = REXML::Document.new File.open( "test.xml" )
116
+ *
117
+ * # Parameter as XML::Smart::Dom
118
+ * require 'xml/smart'
119
+ * oXSLT.xml = XML::Smart.open( "test.xml" )
120
+ *
121
+ * # Parameter as Filename
122
+ * oXSLT.xml = "test.xml"
123
+ */
124
+ VALUE ruby_xslt_xml_obj_set( VALUE self, VALUE xml_doc_obj ) {
125
+ RbTxslt *pRbTxslt;
126
+ Data_Get_Struct( self, RbTxslt, pRbTxslt );
127
+
128
+ pRbTxslt->oXmlObject = xml_doc_obj;
129
+ pRbTxslt->xXmlString = object_to_string( xml_doc_obj );
130
+ if( pRbTxslt->xXmlString == Qnil ) {
131
+ rb_raise( eXSLTError, "Can't get XML data" );
132
+ }
133
+ pRbTxslt->iXmlType = RUBY_XSLT_XMLSRC_TYPE_STR;
134
+ pRbTxslt->xXmlData = pRbTxslt->xXmlString;
135
+
136
+ pRbTxslt->iXmlResultType = RUBY_XSLT_XMLSRC_TYPE_NULL;
137
+
138
+ pRbTxslt->tXMLDocument = parse_xml( STR2CSTR( pRbTxslt->xXmlData ), pRbTxslt->iXmlType );
139
+ if( pRbTxslt->tXMLDocument == NULL ) {
140
+ rb_raise( eXSLTParsingError, "XML parsing error" );
141
+ }
142
+
143
+ pRbTxslt->iXmlType = RUBY_XSLT_XMLSRC_TYPE_PARSED;
144
+
145
+ return( Qnil );
146
+ }
147
+
148
+ /**
149
+ * XML::XSLT#xmlfile=<file> is deprecated. Please use XML::XSLT#xml=<file>
150
+ */
151
+ VALUE ruby_xslt_xml_obj_set_d( VALUE self, VALUE xml_doc_obj ) {
152
+ rb_warn( "XML::XSLT#xmlfile=<file> is deprecated. Please use XML::XSLT#xml=<file> !" );
153
+ return( ruby_xslt_xml_obj_set( self, xml_doc_obj ) );
154
+ }
155
+
156
+ /**
157
+ * string = oXSLT.xml
158
+ *
159
+ * Return XML, set by XML::XSLT#xml=, as string
160
+ */
161
+ VALUE ruby_xslt_xml_2str_get( VALUE self ) {
162
+ RbTxslt *pRbTxslt;
163
+ Data_Get_Struct( self, RbTxslt, pRbTxslt );
164
+
165
+ return( pRbTxslt->xXmlString );
166
+ }
167
+
168
+ /**
169
+ * object = oXSLT.xmlobject
170
+ *
171
+ * Return the XML object set by XML::XSLT#xml=
172
+ */
173
+ VALUE ruby_xslt_xml_2obj_get( VALUE self ) {
174
+ RbTxslt *pRbTxslt;
175
+ Data_Get_Struct( self, RbTxslt, pRbTxslt );
176
+
177
+ return( pRbTxslt->oXmlObject );
178
+ }
179
+
180
+ /**
181
+ * ----------------------------------------------------------------------------
182
+ */
183
+
184
+ /**
185
+ * oXSLT.xsl=<data|REXML::Document|XML::Smart|file>
186
+ *
187
+ * Set XSL data.
188
+ *
189
+ * Parameter can be type String, REXML::Document, XML::Smart::Dom or Filename
190
+ *
191
+ * Examples :
192
+ * # Parameter as String
193
+ * oXSLT.xsl = <<XML
194
+ * <?xml version="1.0" ?>
195
+ * <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
196
+ * <xsl:template match="/">
197
+ * <xsl:apply-templates />
198
+ * </xsl:template>
199
+ * </xsl:stylesheet>
200
+ * XML
201
+ *
202
+ * # Parameter as REXML::Document
203
+ * require 'rexml/document'
204
+ * oXSLT.xsl = REXML::Document.new File.open( "test.xsl" )
205
+ *
206
+ * # Parameter as XML::Smart::Dom
207
+ * require 'xml/smart'
208
+ * oXSLT.xsl = XML::Smart.open( "test.xsl" )
209
+ *
210
+ * # Parameter as Filename
211
+ * oXSLT.xsl = "test.xsl"
212
+ */
213
+ VALUE ruby_xslt_xsl_obj_set( VALUE self, VALUE xsl_doc_obj ) {
214
+ RbTxslt *pRbTxslt;
215
+ Data_Get_Struct( self, RbTxslt, pRbTxslt );
216
+
217
+ pRbTxslt->oXslObject = xsl_doc_obj;
218
+ pRbTxslt->xXslString = object_to_string( xsl_doc_obj );
219
+ if( pRbTxslt->xXslString == Qnil ) {
220
+ rb_raise( eXSLTError, "Can't get XSL data" );
221
+ }
222
+
223
+ if( objectIsFile( xsl_doc_obj ) ) {
224
+ pRbTxslt->iXslType = RUBY_XSLT_XSLSRC_TYPE_FILE;
225
+ pRbTxslt->xXslData = pRbTxslt->oXslObject;
226
+ } else {
227
+ pRbTxslt->iXslType = RUBY_XSLT_XSLSRC_TYPE_STR;
228
+ pRbTxslt->xXslData = pRbTxslt->xXslString;
229
+ }
230
+
231
+ pRbTxslt->iXmlResultType = RUBY_XSLT_XMLSRC_TYPE_NULL;
232
+
233
+ pRbTxslt->tParsedXslt = parse_xsl( STR2CSTR( pRbTxslt->xXslData ), pRbTxslt->iXslType );
234
+ if( pRbTxslt->tParsedXslt == NULL ) {
235
+ rb_raise( eXSLTParsingError, "XSL Stylesheet parsing error" );
236
+ }
237
+
238
+ pRbTxslt->iXslType = RUBY_XSLT_XSLSRC_TYPE_PARSED;
239
+
240
+ return( Qnil );
241
+ }
242
+
243
+ /**
244
+ * XML::XSLT#xslfile=<file> is deprecated. Please use XML::XSLT#xsl=<file>
245
+ */
246
+ VALUE ruby_xslt_xsl_obj_set_d( VALUE self, VALUE xsl_doc_obj ) {
247
+ rb_warning( "XML::XSLT#xslfile=<file> is deprecated. Please use XML::XSLT#xsl=<file> !" );
248
+ return( ruby_xslt_xsl_obj_set( self, xsl_doc_obj ) );
249
+ }
250
+
251
+ /**
252
+ * string = oXSLT.xsl
253
+ *
254
+ * Return XSL, set by XML::XSLT#xsl=, as string
255
+ */
256
+ VALUE ruby_xslt_xsl_2str_get( VALUE self ) {
257
+ RbTxslt *pRbTxslt;
258
+ Data_Get_Struct( self, RbTxslt, pRbTxslt );
259
+
260
+ return( pRbTxslt->xXslString );
261
+ }
262
+
263
+ /**
264
+ * object = oXSLT.xslobject
265
+ *
266
+ * Return the XSL object set by XML::XSLT#xsl=
267
+ */
268
+ VALUE ruby_xslt_xsl_2obj_get( VALUE self ) {
269
+ RbTxslt *pRbTxslt;
270
+ Data_Get_Struct( self, RbTxslt, pRbTxslt );
271
+
272
+ return( pRbTxslt->oXslObject );
273
+ }
274
+
275
+ /**
276
+ * ----------------------------------------------------------------------------
277
+ */
278
+
279
+ /**
280
+ * output_string = oXSLT.serve( )
281
+ *
282
+ * Return the stylesheet transformation
283
+ */
284
+ VALUE ruby_xslt_serve( VALUE self ) {
285
+ RbTxslt *pRbTxslt;
286
+ char *xOut;
287
+ char **pxParams = NULL;
288
+
289
+ Data_Get_Struct( self, RbTxslt, pRbTxslt );
290
+
291
+ if( pRbTxslt->iXmlResultType == RUBY_XSLT_XMLSRC_TYPE_NULL ) {
292
+
293
+ if( pRbTxslt->pxParams != Qnil ){
294
+ int iCpt;
295
+
296
+ pxParams = (char **)ALLOCA_N( void *, pRbTxslt->iNbParams );
297
+ MEMZERO( pxParams, void *, pRbTxslt->iNbParams );
298
+
299
+ for( iCpt = 0; iCpt <= pRbTxslt->iNbParams - 3; iCpt++ ) {
300
+ pxParams[iCpt] = STR2CSTR( rb_ary_entry( pRbTxslt->pxParams, iCpt ) );
301
+ }
302
+ }
303
+
304
+ if( pRbTxslt->iXslType != RUBY_XSLT_XSLSRC_TYPE_NULL &&
305
+ pRbTxslt->iXmlType != RUBY_XSLT_XMLSRC_TYPE_NULL ) {
306
+ xOut = parse( pRbTxslt->tParsedXslt, pRbTxslt->tXMLDocument, pxParams );
307
+ if( xOut == NULL ) {
308
+ pRbTxslt->xXmlResultCache = Qnil;
309
+ pRbTxslt->iXmlResultType = RUBY_XSLT_XMLSRC_TYPE_NULL;
310
+ } else {
311
+ pRbTxslt->xXmlResultCache = rb_str_new2( xOut );
312
+ pRbTxslt->iXmlResultType = RUBY_XSLT_XMLSRC_TYPE_STR;
313
+ }
314
+ } else {
315
+ pRbTxslt->xXmlResultCache = Qnil;
316
+ pRbTxslt->iXmlResultType = RUBY_XSLT_XMLSRC_TYPE_NULL;
317
+ }
318
+ }
319
+
320
+ return( pRbTxslt->xXmlResultCache );
321
+ }
322
+
323
+ /**
324
+ * oXSLT.save( "result.xml" )
325
+ *
326
+ * Save the stylesheet transformation to file
327
+ */
328
+ VALUE ruby_xslt_save( VALUE self, VALUE xOutFilename ) {
329
+ char *xOut;
330
+ VALUE rOut;
331
+ FILE *fOutFile;
332
+
333
+ rOut = ruby_xslt_serve( self );
334
+
335
+ if( rOut != Qnil ) {
336
+ xOut = STR2CSTR( rOut );
337
+
338
+ fOutFile = fopen( STR2CSTR( xOutFilename ), "w" );
339
+ if( fOutFile == NULL ) {
340
+ free( xOut );
341
+ rb_raise( rb_eRuntimeError, "Can't create file %s\n", STR2CSTR( xOutFilename ) );
342
+ rOut = Qnil;
343
+ } else {
344
+ fwrite( xOut, 1, strlen( xOut ), fOutFile );
345
+ fclose( fOutFile );
346
+ }
347
+ }
348
+
349
+ return( rOut );
350
+ }
351
+
352
+ /**
353
+ * ----------------------------------------------------------------------------
354
+ */
355
+
356
+ #ifdef USE_ERROR_HANDLER
357
+ /**
358
+ * Brendan Taylor
359
+ * whateley@gmail.com
360
+ */
361
+ /**
362
+ * error_ary = XML::XSLT::errors( )
363
+ *
364
+ * Return an Array containing all the xml errors
365
+ *
366
+ * This method is only available if Ruby/XSLT has been configured with --enable-error-handler option
367
+ */
368
+ VALUE rb_xslt_errors(VALUE class) {
369
+ return rb_cvar_get(class, rb_intern("@@errors"));
370
+ }
371
+
372
+ void xsltErrorFuncHandler(void *ctx, const char *msg, ...) {
373
+ va_list ap;
374
+ char *str;
375
+ char *larger;
376
+ int chars;
377
+ int size = 150;
378
+
379
+ VALUE error_arr = rb_cvar_get(cXSLT, rb_intern("@@errors"));
380
+
381
+ /* this is taken verbatim from the libxslt python bindings */
382
+ str = (char *) xmlMalloc(150);
383
+ if (str == NULL)
384
+ return;
385
+
386
+ while (1) {
387
+ va_start(ap, msg);
388
+ chars = vsnprintf(str, size, msg, ap);
389
+ va_end(ap);
390
+ if ((chars > -1) && (chars < size))
391
+ break;
392
+ if (chars > -1)
393
+ size += chars + 1;
394
+ else
395
+ size += 100;
396
+ if ((larger = (char *) xmlRealloc(str, size)) == NULL) {
397
+ xmlFree(str);
398
+ return;
399
+ }
400
+ str = larger;
401
+ }
402
+
403
+ rb_ary_push(error_arr, rb_str_new2(str));
404
+ }
405
+ #endif
406
+
407
+ /**
408
+ * ----------------------------------------------------------------------------
409
+ */
410
+
411
+ /**
412
+ * parameters support, patch from :
413
+ *
414
+ * Eustáquio "TaQ" Rangel
415
+ * eustaquiorangel@yahoo.com
416
+ * http://beam.to/taq
417
+ *
418
+ * Corrections : Greg
419
+ */
420
+ /**
421
+ * oXSLT.parameters={ "key" => "value", "key" => "value", ... }
422
+ */
423
+ VALUE ruby_xslt_parameters_set( VALUE self, VALUE parameters ) {
424
+ RbTxslt *pRbTxslt;
425
+ Check_Type( parameters, T_HASH );
426
+
427
+ Data_Get_Struct( self, RbTxslt, pRbTxslt );
428
+
429
+ if( !NIL_P(parameters) ){
430
+ pRbTxslt->pxParams = rb_ary_new( );
431
+ // each_pair and process_pair defined ind parameters.c
432
+ (void)rb_iterate( each_pair, parameters, process_pair, pRbTxslt->pxParams );
433
+ pRbTxslt->iNbParams = FIX2INT( rb_funcall( parameters, rb_intern("size"), 0, 0 ) ) * 2 + 2;
434
+ pRbTxslt->iXmlResultType = RUBY_XSLT_XMLSRC_TYPE_NULL;
435
+ }
436
+
437
+ return( Qnil );
438
+ }
439
+
440
+ /**
441
+ * ----------------------------------------------------------------------------
442
+ */
443
+
444
+ /**
445
+ * media type information, path from :
446
+ *
447
+ * Brendan Taylor
448
+ * whateley@gmail.com
449
+ *
450
+ */
451
+ /**
452
+ * mediaTypeString = oXSLT.mediaType( )
453
+ *
454
+ * Return the XSL output's media type
455
+ */
456
+ VALUE ruby_xslt_media_type( VALUE self ) {
457
+ RbTxslt *pRbTxslt;
458
+ xsltStylesheetPtr vXSLTSheet = NULL;
459
+
460
+ Data_Get_Struct( self, RbTxslt, pRbTxslt );
461
+
462
+ vXSLTSheet = pRbTxslt->tParsedXslt;
463
+
464
+ if ( (vXSLTSheet == NULL) || (vXSLTSheet->mediaType == NULL) ) {
465
+ return Qnil;
466
+ } else {
467
+ return rb_str_new2( (char *)(vXSLTSheet->mediaType) );
468
+ }
469
+ }
470
+
471
+ /**
472
+ * ----------------------------------------------------------------------------
473
+ */
474
+
475
+ /**
476
+ * XML::XSLT::extFunction( "round-trip", "http://test.none", rbObj )
477
+ * registers an extension function "round-trip" in the namespace "http://test.none"
478
+ *
479
+ * when XPath like ex:round-trip(arg) is encountered in the XSLT it will call the method "round_trip" on the rbObj object with the argument arg
480
+ */
481
+ VALUE ruby_xslt_ext_function( VALUE class, VALUE name, VALUE ns_uri, VALUE receiver ) {
482
+ VALUE ns_hash, func_hash;
483
+
484
+ ns_hash = rb_cvar_get(cXSLT, rb_intern("@@extFunctions"));
485
+
486
+ func_hash = rb_hash_aref(ns_hash, ns_uri);
487
+
488
+ if(func_hash == Qnil) {
489
+ /* we've seen no reference to this URI, so create one */
490
+ func_hash = rb_hash_new();
491
+ rb_hash_aset(ns_hash, ns_uri, func_hash);
492
+ }
493
+
494
+ rb_hash_aset(func_hash, name, receiver);
495
+
496
+ xsltRegisterExtModuleFunction( BAD_CAST STR2CSTR(name), BAD_CAST STR2CSTR(ns_uri), xmlXPathFuncCallback );
497
+
498
+ return Qnil;
499
+ }
500
+
501
+ /**
502
+ * string = oXSLT.xsl_to_s( )
503
+ */
504
+ VALUE ruby_xslt_to_s( VALUE self ) {
505
+ VALUE vStrOut;
506
+ RbTxslt *pRbTxslt;
507
+ xsltStylesheetPtr vXSLTSheet = NULL;
508
+ char *xKlassName = rb_class2name( CLASS_OF( self ) );
509
+
510
+ Data_Get_Struct( self, RbTxslt, pRbTxslt );
511
+
512
+ //vXSLTSheet = xsltParseStylesheetDoc( xmlParseMemory( STR2CSTR( pRbTxslt->xXslData ), strlen( STR2CSTR( pRbTxslt->xXslData ) ) ) );
513
+ vXSLTSheet = pRbTxslt->tParsedXslt;
514
+ if (vXSLTSheet == NULL) return Qnil;
515
+
516
+ vStrOut = rb_str_new( 0, strlen(xKlassName)+1024 );
517
+ (void) sprintf( RSTRING(vStrOut)->ptr,
518
+ "#<%s: parent=%p,next=%p,imports=%p,docList=%p,"
519
+ "doc=%p,stripSpaces=%p,stripAll=%d,cdataSection=%p,"
520
+ "variables=%p,templates=%p,templatesHash=%p,"
521
+ "rootMatch=%p,keyMatch=%p,elemMatch=%p,"
522
+ "attrMatch=%p,parentMatch=%p,textMatch=%p,"
523
+ "piMatch=%p,commentMatch=%p,nsAliases=%p,"
524
+ "attributeSets=%p,nsHash=%p,nsDefs=%p,keys=%p,"
525
+ "method=%s,methodURI=%s,version=%s,encoding=%s,"
526
+ "omitXmlDeclaration=%d,decimalFormat=%p,standalone=%d,"
527
+ "doctypePublic=%s,doctypeSystem=%s,indent=%d,"
528
+ "mediaType=%s,preComps=%p,warnings=%d,errors=%d,"
529
+ "exclPrefix=%s,exclPrefixTab=%p,exclPrefixNr=%d,"
530
+ "exclPrefixMax=%d>",
531
+ xKlassName,
532
+ vXSLTSheet->parent, vXSLTSheet->next, vXSLTSheet->imports, vXSLTSheet->docList,
533
+ vXSLTSheet->doc, vXSLTSheet->stripSpaces, vXSLTSheet->stripAll, vXSLTSheet->cdataSection,
534
+ vXSLTSheet->variables, vXSLTSheet->templates, vXSLTSheet->templatesHash,
535
+ vXSLTSheet->rootMatch, vXSLTSheet->keyMatch, vXSLTSheet->elemMatch,
536
+ vXSLTSheet->attrMatch, vXSLTSheet->parentMatch, vXSLTSheet->textMatch,
537
+ vXSLTSheet->piMatch, vXSLTSheet->commentMatch, vXSLTSheet->nsAliases,
538
+ vXSLTSheet->attributeSets, vXSLTSheet->nsHash, vXSLTSheet->nsDefs, vXSLTSheet->keys,
539
+ vXSLTSheet->method, vXSLTSheet->methodURI, vXSLTSheet->version, vXSLTSheet->encoding,
540
+ vXSLTSheet->omitXmlDeclaration, vXSLTSheet->decimalFormat, vXSLTSheet->standalone,
541
+ vXSLTSheet->doctypePublic, vXSLTSheet->doctypeSystem, vXSLTSheet->indent,
542
+ vXSLTSheet->mediaType, vXSLTSheet->preComps, vXSLTSheet->warnings, vXSLTSheet->errors,
543
+ vXSLTSheet->exclPrefix, vXSLTSheet->exclPrefixTab, vXSLTSheet->exclPrefixNr,
544
+ vXSLTSheet->exclPrefixMax );
545
+
546
+ RSTRING(vStrOut)->len = strlen( RSTRING(vStrOut)->ptr );
547
+ if( OBJ_TAINTED(self) ) OBJ_TAINT(vStrOut);
548
+
549
+ // xsltFreeStylesheet(vXSLTSheet);
550
+
551
+ return( vStrOut );
552
+ }
553
+
554
+ /**
555
+ * ----------------------------------------------------------------------------
556
+ */
557
+
558
+ void Init_xslt( void ) {
559
+ mXML = rb_define_module( "XML" );
560
+ cXSLT = rb_define_class_under( mXML, "XSLT", rb_cObject );
561
+
562
+ eXSLTError = rb_define_class_under( cXSLT, "XSLTError", rb_eRuntimeError );
563
+ eXSLTParsingError = rb_define_class_under( cXSLT, "ParsingError", eXSLTError );
564
+ eXSLTTransformationError = rb_define_class_under( cXSLT, "TransformationError", eXSLTError );
565
+
566
+ rb_define_const( cXSLT, "MAX_DEPTH", INT2NUM(xsltMaxDepth) );
567
+ rb_define_const( cXSLT, "MAX_SORT", INT2NUM(XSLT_MAX_SORT) );
568
+ rb_define_const( cXSLT, "ENGINE_VERSION", rb_str_new2(xsltEngineVersion) );
569
+ rb_define_const( cXSLT, "LIBXSLT_VERSION", INT2NUM(xsltLibxsltVersion) );
570
+ rb_define_const( cXSLT, "LIBXML_VERSION", INT2NUM(xsltLibxmlVersion) );
571
+ rb_define_const( cXSLT, "XSLT_NAMESPACE", rb_str_new2((char *)XSLT_NAMESPACE) );
572
+ rb_define_const( cXSLT, "DEFAULT_VENDOR", rb_str_new2(XSLT_DEFAULT_VENDOR) );
573
+ rb_define_const( cXSLT, "DEFAULT_VERSION", rb_str_new2(XSLT_DEFAULT_VERSION) );
574
+ rb_define_const( cXSLT, "DEFAULT_URL", rb_str_new2(XSLT_DEFAULT_URL) );
575
+ rb_define_const( cXSLT, "NAMESPACE_LIBXSLT", rb_str_new2((char *)XSLT_LIBXSLT_NAMESPACE) );
576
+ rb_define_const( cXSLT, "NAMESPACE_NORM_SAXON", rb_str_new2((char *)XSLT_NORM_SAXON_NAMESPACE) );
577
+ rb_define_const( cXSLT, "NAMESPACE_SAXON", rb_str_new2((char *)XSLT_SAXON_NAMESPACE) );
578
+ rb_define_const( cXSLT, "NAMESPACE_XT", rb_str_new2((char *)XSLT_XT_NAMESPACE) );
579
+ rb_define_const( cXSLT, "NAMESPACE_XALAN", rb_str_new2((char *)XSLT_XALAN_NAMESPACE) );
580
+
581
+ rb_define_const( cXSLT, "RUBY_XSLT_VERSION", rb_str_new2(RUBY_XSLT_VERSION) );
582
+
583
+ rb_define_singleton_method( cXSLT, "new", ruby_xslt_new, 0 );
584
+ rb_define_singleton_method( cXSLT, "extFunction", ruby_xslt_ext_function, 3);
585
+
586
+ /* a hash of hashes. might be more elegant if it were its own class */
587
+ /* keeps track of what functions are registered in what namespaces */
588
+ rb_define_class_variable( cXSLT, "@@extFunctions", rb_hash_new());
589
+
590
+ rb_define_method( cXSLT, "serve", ruby_xslt_serve, 0 );
591
+ rb_define_method( cXSLT, "save", ruby_xslt_save, 1 );
592
+
593
+ rb_define_method( cXSLT, "xml=", ruby_xslt_xml_obj_set, 1 );
594
+ rb_define_method( cXSLT, "xmlfile=", ruby_xslt_xml_obj_set_d, 1 ); // DEPRECATED
595
+ rb_define_method( cXSLT, "xml", ruby_xslt_xml_2str_get, 0 );
596
+ rb_define_method( cXSLT, "xmlobject", ruby_xslt_xml_2obj_get, 0 );
597
+
598
+ rb_define_method( cXSLT, "xsl=", ruby_xslt_xsl_obj_set, 1 );
599
+ rb_define_method( cXSLT, "xslfile=", ruby_xslt_xsl_obj_set_d, 1 ); // DEPRECATED
600
+ rb_define_method( cXSLT, "xsl", ruby_xslt_xsl_2str_get, 0 );
601
+ rb_define_method( cXSLT, "xslobject", ruby_xslt_xsl_2obj_get, 0 );
602
+
603
+ rb_define_method( cXSLT, "parameters=", ruby_xslt_parameters_set, 1 );
604
+ rb_define_method( cXSLT, "xsl_to_s", ruby_xslt_to_s, 0 );
605
+
606
+ rb_define_method( cXSLT, "mediaType", ruby_xslt_media_type, 0 );
607
+
608
+ #ifdef USE_ERROR_HANDLER
609
+ /* this is really quite inelegant */
610
+ xmlSetGenericErrorFunc( NULL, xsltErrorFuncHandler );
611
+ xsltSetGenericErrorFunc( NULL, xsltErrorFuncHandler );
612
+ rb_define_class_variable( cXSLT, "@@errors", rb_ary_new());
613
+ rb_define_singleton_method( cXSLT, "errors", rb_xslt_errors, 0 );
614
+ #endif
615
+
616
+ #ifdef USE_EXSLT
617
+ exsltRegisterAll();
618
+ #endif
619
+ }