ruby-xslt 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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