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.
@@ -0,0 +1,20 @@
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
+ VALUE each_pair( VALUE );
20
+ VALUE process_pair( VALUE, VALUE );
@@ -0,0 +1,228 @@
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
+ #include "parser.h"
21
+
22
+ extern VALUE cXSLT;
23
+
24
+ xmlDocPtr parse_xml( char* xml, int iXmlType ) {
25
+ xmlDocPtr tXMLDocument = NULL;
26
+
27
+ #ifdef USE_ERROR_HANDLER
28
+ VALUE error_arr = rb_cvar_get(cXSLT, rb_intern("@@errors"));
29
+ int iInitialNumberOfErrors = RARRAY(error_arr)->len;
30
+ #endif
31
+
32
+ /** Act: Parse XML */
33
+ if( iXmlType == RUBY_XSLT_XMLSRC_TYPE_STR ) {
34
+ tXMLDocument = xmlParseMemory( xml, strlen( xml ) );
35
+ } else if( iXmlType == RUBY_XSLT_XMLSRC_TYPE_FILE ) {
36
+ tXMLDocument = xmlParseFile( xml );
37
+ }
38
+
39
+ if( tXMLDocument == NULL ) {
40
+ rb_raise( eXSLTParsingError, "XML parsing error" );
41
+ return( NULL );
42
+ }
43
+
44
+ #ifdef USE_ERROR_HANDLER
45
+ if(RARRAY(error_arr)->len > iInitialNumberOfErrors) {
46
+ rb_raise( eXSLTTransformationError, "Stylesheet transformation error" );
47
+ }
48
+ #endif
49
+
50
+ return( tXMLDocument );
51
+ }
52
+
53
+ xsltStylesheetPtr parse_xsl( char* xsl, int iXslType ) {
54
+ xsltStylesheetPtr tParsedXslt = NULL;
55
+ xmlDocPtr tXSLDocument = NULL;
56
+
57
+ /** Rem: For encoding */
58
+ xmlCharEncodingHandlerPtr encoder = NULL;
59
+ const xmlChar *encoding = NULL;
60
+
61
+ #ifdef USE_ERROR_HANDLER
62
+ VALUE error_arr = rb_cvar_get(cXSLT, rb_intern("@@errors"));
63
+ int iInitialNumberOfErrors = RARRAY(error_arr)->len;
64
+ #endif
65
+
66
+ /** Act: Encoding support */
67
+ xmlInitCharEncodingHandlers( );
68
+
69
+ /** Act: Parse XSL */
70
+ if( iXslType == RUBY_XSLT_XSLSRC_TYPE_STR ) {
71
+ tXSLDocument = xmlParseMemory( xsl, strlen( xsl ) );
72
+ if( tXSLDocument == NULL ) {
73
+ rb_raise( eXSLTParsingError, "XSL parsing error" );
74
+ return( NULL );
75
+ }
76
+
77
+ tParsedXslt = xsltParseStylesheetDoc( tXSLDocument );
78
+ } else if( iXslType == RUBY_XSLT_XSLSRC_TYPE_FILE ) {
79
+ tParsedXslt = xsltParseStylesheetFile( BAD_CAST xsl );
80
+ }
81
+
82
+ if( tParsedXslt == NULL ) {
83
+ rb_raise( eXSLTParsingError, "XSL Stylesheet parsing error" );
84
+ return( NULL );
85
+ }
86
+
87
+ /** Act: Get encoding */
88
+ XSLT_GET_IMPORT_PTR( encoding, tParsedXslt, encoding )
89
+ encoder = xmlFindCharEncodingHandler((char *)encoding);
90
+
91
+ if( encoding != NULL ) {
92
+ encoder = xmlFindCharEncodingHandler((char *)encoding);
93
+ if( (encoder != NULL) && (xmlStrEqual((const xmlChar *)encoder->name, (const xmlChar *) "UTF-8")) ) {
94
+ encoder = NULL;
95
+ }
96
+ }
97
+
98
+ #ifdef USE_ERROR_HANDLER
99
+ if(RARRAY(error_arr)->len > iInitialNumberOfErrors) {
100
+ rb_raise( eXSLTTransformationError, "Stylesheet transformation error" );
101
+ }
102
+ #endif
103
+
104
+ return( tParsedXslt );
105
+ }
106
+
107
+ /**
108
+ * xOut = parser( char *xml, int iXmlType, char *xslt, int iXslType, char **pxParams );
109
+ */
110
+ char* parse( xsltStylesheetPtr tParsedXslt, xmlDocPtr tXMLDocument, char **pxParams ) {
111
+ xmlDocPtr tXMLDocumentResult = NULL;
112
+ int iXMLDocumentResult;
113
+ xmlChar *tXMLDocumentResultString;
114
+ int tXMLDocumentResultLenght;
115
+
116
+ #ifdef USE_ERROR_HANDLER
117
+ VALUE error_arr = rb_cvar_get(cXSLT, rb_intern("@@errors"));
118
+ int iInitialNumberOfErrors = RARRAY(error_arr)->len;
119
+ #endif
120
+
121
+ tXMLDocumentResult = xsltApplyStylesheet( tParsedXslt, tXMLDocument, (const char**) pxParams );
122
+ if( tXMLDocumentResult == NULL ) {
123
+ rb_raise( eXSLTTransformationError, "Stylesheet transformation error" );
124
+ return( NULL );
125
+ }
126
+
127
+ iXMLDocumentResult = xsltSaveResultToString( &tXMLDocumentResultString, &tXMLDocumentResultLenght, tXMLDocumentResult, tParsedXslt );
128
+
129
+ xmlFreeDoc(tXMLDocumentResult);
130
+
131
+ #ifdef USE_ERROR_HANDLER
132
+ if(RARRAY(error_arr)->len > iInitialNumberOfErrors) {
133
+ rb_raise( eXSLTTransformationError, "Stylesheet transformation error" );
134
+ }
135
+ #endif
136
+
137
+ return((char*)tXMLDocumentResultString);
138
+ }
139
+
140
+ /**
141
+ * vOut = object_to_string( VALUE object );
142
+ */
143
+ VALUE object_to_string( VALUE object ) {
144
+ VALUE vOut = Qnil;
145
+
146
+ switch( TYPE( object ) ) {
147
+ case T_STRING:
148
+ {
149
+ if( isFile( STR2CSTR( object ) ) == 0 ) {
150
+ vOut = object;
151
+ } else {
152
+ long iBufferLength;
153
+ long iCpt;
154
+ char *xBuffer;
155
+
156
+ FILE* fStream = fopen( STR2CSTR( object ), "r" );
157
+ if( fStream == NULL ) {
158
+ return( Qnil );
159
+ }
160
+
161
+ fseek( fStream, 0L, 2 );
162
+ iBufferLength = ftell( fStream );
163
+ xBuffer = (char *)malloc( (int)iBufferLength + 1 );
164
+ if( !xBuffer )
165
+ rb_raise( rb_eNoMemError, "Memory allocation error" );
166
+
167
+ xBuffer[iBufferLength] = 0;
168
+ fseek( fStream, 0L, 0 );
169
+ iCpt = fread( xBuffer, 1, (int)iBufferLength, fStream );
170
+
171
+ if( iCpt != iBufferLength ) {
172
+ free( (char *)xBuffer );
173
+ rb_raise( rb_eSystemCallError, "Read file error" );
174
+ }
175
+
176
+ vOut = rb_str_new2( xBuffer );
177
+ free( xBuffer );
178
+
179
+ fclose( fStream );
180
+ }
181
+ }
182
+ break;
183
+
184
+ case T_DATA:
185
+ case T_OBJECT:
186
+ {
187
+ if( strcmp( getRubyObjectName( object ), "XML::Smart::Dom" ) == 0 ||
188
+ strcmp( getRubyObjectName( object ), "XML::Simple::Dom" ) == 0 ) {
189
+ vOut = rb_funcall( object, rb_intern( "to_s" ), 0 );
190
+ } else if ( strcmp( getRubyObjectName( object ), "REXML::Document" ) == 0 ) {
191
+ vOut = rb_funcall( object, rb_intern( "to_s" ), 0 );
192
+ } else {
193
+ rb_raise( rb_eSystemCallError, "Can't read XML from object %s", getRubyObjectName( object ) );
194
+ }
195
+ }
196
+ break;
197
+
198
+ default:
199
+ rb_raise( rb_eArgError, "XML object #0x%x not supported", TYPE( object ) );
200
+ }
201
+
202
+ return( vOut );
203
+ }
204
+
205
+ /**
206
+ * bOut = objectIsFile( VALUE object );
207
+ */
208
+ int objectIsFile( VALUE object ) {
209
+ int bOut = 0;
210
+
211
+ switch( TYPE( object ) ) {
212
+ case T_STRING:
213
+ {
214
+ if( isFile( STR2CSTR( object ) ) == 0 )
215
+ bOut = 0;
216
+ else
217
+ bOut = 1;
218
+ }
219
+ break;
220
+
221
+ case T_DATA:
222
+ case T_OBJECT:
223
+ default:
224
+ bOut = 0;
225
+ }
226
+
227
+ return( bOut );
228
+ }
@@ -0,0 +1,30 @@
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
+ #ifndef __RUBY_XSLT_PARSER_H__
20
+ #define __RUBY_XSLT_PARSER_H__
21
+ extern int xmlLoadExtDtdDefaultValue;
22
+
23
+ xmlDocPtr parse_xml( char* , int );
24
+ xsltStylesheetPtr parse_xsl( char*, int );
25
+ char* parse( xsltStylesheetPtr, xmlDocPtr, char ** );
26
+
27
+ VALUE object_to_string( VALUE );
28
+ int objectIsFile( VALUE );
29
+ #endif
30
+
@@ -0,0 +1,30 @@
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
+ #include "rb_utils.h"
19
+
20
+ char * getRubyObjectName( VALUE rb_Object ) {
21
+ VALUE klass = rb_funcall( rb_Object, rb_intern( "class" ), 0 );
22
+ return( STR2CSTR( rb_funcall( klass, rb_intern( "to_s" ), 0 ) ) );
23
+ }
24
+
25
+ int isFile( const char *filename ) {
26
+ struct stat stbuf;
27
+
28
+ if( stat( filename, &stbuf ) ) return 0;
29
+ return( ( (stbuf.st_mode & S_IFMT) == S_IFREG ) ? 1 : 0 );
30
+ }
@@ -0,0 +1,34 @@
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
+ /* Please see the LICENSE file for copyright and distribution information */
20
+
21
+ #ifndef __RUBY_RB_UTILS_H__
22
+ #define __RUBY_RB_UTILS_H__
23
+
24
+ #include <ruby.h>
25
+ #include <rubyio.h>
26
+
27
+ #include <stdio.h>
28
+ #include <string.h>
29
+ #include <sys/stat.h>
30
+
31
+ char * getRubyObjectName( VALUE );
32
+ int isFile( const char *filename );
33
+
34
+ #endif
@@ -0,0 +1,19 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = %q{ruby-xslt}
3
+ s.version = "0.9.2"
4
+ s.date = %q{2005-11-17}
5
+ s.summary = %q{A Ruby class for processing XSLT}
6
+ s.email = %q{greg@webtime-project.net}
7
+ s.homepage = %q{http://raa.ruby-lang.org/project/ruby-xslt/}
8
+ s.description = %q{Ruby/XSLT is a simple XSLT class based on libxml <http://xmlsoft.org/> and libxslt <http://xmlsoft.org/XSLT/>}
9
+ s.has_rdoc = true
10
+ s.authors = ["Gregoire Lejeune"]
11
+ candidates = Dir.glob("{.,debug,examples,tests}/*")
12
+ s.files = candidates.delete_if do |item|
13
+ item.include?("CVS") || item.include?("rdoc")
14
+ end
15
+ s.test_files = ["tests/test.rb"]
16
+ s.rdoc_options = ["--title", "Ruby/XSLT", "--main", "README", "--line-numbers"]
17
+ s.extra_rdoc_files = ["README", "AUTHORS", "COPYING", "ChangeLog"]
18
+ s.extensions = ["extconf.rb"]
19
+ end
@@ -0,0 +1,2 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <test>This is a test file</test>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" ?>
2
+ <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
3
+ <xsl:template match="/">
4
+ <xsl:apply-templates />
5
+ </xsl:template>
6
+ </xsl:stylesheet>
@@ -0,0 +1,125 @@
1
+ #!ruby
2
+
3
+ require "test/unit"
4
+ require "../xslt"
5
+
6
+ # Test::Unit suite for flattenx extension
7
+ #
8
+ # $Id: test.rb,v 1.4 2005/11/14 00:22:27 whateley Exp $
9
+ # $Author: whateley $
10
+
11
+ class XsltTest < Test::Unit::TestCase
12
+ def setup
13
+ if @xslt.nil? == true
14
+ @xslt = XML::XSLT.new( )
15
+ @testOut = "<?xml version=\"1.0\"?>\nThis is a test file\n"
16
+ @xml_simple = true
17
+ begin
18
+ require "xml/simple"
19
+ rescue LoadError => e
20
+ @xml_simple = false
21
+ end
22
+
23
+ @xml_smart = true
24
+ begin
25
+ require "xml/smart"
26
+ rescue LoadError => e
27
+ @xml_smart = false
28
+ end
29
+ end
30
+ end
31
+
32
+ def test_instance
33
+ assert_instance_of( XML::XSLT, @xslt )
34
+ end
35
+
36
+ def test_from_file
37
+ @xslt.xml = "t.xml"
38
+ @xslt.xsl = "t.xsl"
39
+ out = @xslt.serve
40
+ assert_equal( @testOut, out )
41
+ end
42
+
43
+ def test_from_data
44
+ @xslt.xml = IO::readlines( "t.xml" ).join
45
+ @xslt.xsl = IO::readlines( "t.xsl" ).join
46
+ out = @xslt.serve
47
+ assert_equal( @testOut, out )
48
+ end
49
+
50
+ def test_from_simple
51
+ if @xml_simple
52
+ require 'xml/simple'
53
+ @xslt.xml = XML::Simple.open( "t.xml" )
54
+ @xslt.xsl = XML::Simple.open( "t.xsl" )
55
+ out = @xslt.serve()
56
+ assert_equal( @testOut, out )
57
+ else
58
+ assert( true )
59
+ end
60
+ end
61
+
62
+ def test_from_smart
63
+ if @xml_smart
64
+ require 'xml/smart'
65
+ @xslt.xml = XML::Smart.open( "t.xml" )
66
+ @xslt.xsl = XML::Smart.open( "t.xsl" )
67
+ out = @xslt.serve()
68
+ assert_equal( @testOut, out )
69
+ else
70
+ assert( true )
71
+ end
72
+ end
73
+
74
+ def test_from_rexml
75
+ require 'rexml/document'
76
+ @xslt.xml = REXML::Document.new File.open( "t.xml" )
77
+ @xslt.xsl = REXML::Document.new File.open( "t.xsl" )
78
+ out = @xslt.serve()
79
+ assert_equal( @testOut, out )
80
+ end
81
+
82
+ def test_error_1
83
+ begin
84
+ @xslt.xsl = "nil"
85
+ rescue => e
86
+ assert_instance_of( XML::XSLT::ParsingError, e )
87
+ end
88
+ end
89
+
90
+ def test_error_2
91
+ begin
92
+ @xslt.xml = "nil"
93
+ rescue => e
94
+ assert_instance_of( XML::XSLT::ParsingError, e )
95
+ end
96
+ end
97
+
98
+ def test_error_3
99
+ begin
100
+ @xslt.xml = "t.xsl"
101
+ rescue => e
102
+ assert_instance_of( XML::XSLT::ParsingError, e )
103
+ end
104
+ end
105
+
106
+ def test_base_uri_1
107
+ @xslt.xml = "<test/>"
108
+ xsl = "subdir/test.xsl"
109
+
110
+ # the base URI of a loaded XSL file should be the URI of that file
111
+ assert_nothing_raised( XML::XSLT::ParsingError ) do
112
+ @xslt.xsl = xsl
113
+ end
114
+ end
115
+
116
+ def test_base_uri_2
117
+ @xslt.xml = "<test/>"
118
+ xsl = File.read("subdir/test.xsl")
119
+
120
+ # a file loaded from memory has no base URI, so this should fail
121
+ assert_raises( XML::XSLT::ParsingError ) do
122
+ @xslt.xsl = xsl
123
+ end
124
+ end
125
+ end