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/AUTHORS +23 -0
- data/COPYING +340 -0
- data/ChangeLog +64 -0
- data/README +137 -0
- data/debug/memwatch.c +2664 -0
- data/debug/memwatch.h +707 -0
- data/examples/commentary.dtd +34 -0
- data/examples/functions.xsl +51 -0
- data/examples/fuzface.rb +13 -0
- data/examples/fuzface.xml +154 -0
- data/examples/fuzface.xsl +4 -0
- data/examples/fuzface_REXML.rb +11 -0
- data/examples/fuzface_XML-Simple.rb +12 -0
- data/examples/fuzface_data.rb +13 -0
- data/examples/fuzface_error.rb +86 -0
- data/examples/fuzface_to_s.rb +9 -0
- data/examples/info.rb +19 -0
- data/examples/ramblings.xsl +46 -0
- data/examples/test.xml +5 -0
- data/examples/test.xsl +18 -0
- data/examples/test_functions.rb +18 -0
- data/examples/test_parameters.rb +13 -0
- data/extconf.rb +114 -0
- data/extfunc.c +216 -0
- data/extfunc.h +26 -0
- data/parameters.c +59 -0
- data/parameters.h +20 -0
- data/parser.c +228 -0
- data/parser.h +30 -0
- data/rb_utils.c +30 -0
- data/rb_utils.h +34 -0
- data/ruby-xslt.gemspec +19 -0
- data/tests/t.xml +2 -0
- data/tests/t.xsl +6 -0
- data/tests/test.rb +125 -0
- data/xslt.c +619 -0
- data/xslt.h +98 -0
- metadata +98 -0
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
|
+
}
|