libxslt-ruby 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/README +125 -136
  2. data/doc/classes/XSLT.html +215 -0
  3. data/doc/classes/XSLT/Stylesheet.html +244 -0
  4. data/doc/classes/XSLT/TransformContext.html +111 -0
  5. data/doc/created.rid +1 -0
  6. data/doc/files/CHANGES.html +168 -0
  7. data/doc/files/LICENSE.html +133 -0
  8. data/doc/files/README.html +269 -0
  9. data/doc/files/ext/libxslt/libxslt_c.html +101 -0
  10. data/doc/files/ext/libxslt/ruby_xslt_stylesheet_c.html +101 -0
  11. data/doc/files/ext/libxslt/ruby_xslt_transform_context_c.html +101 -0
  12. data/doc/files/lib/deprecated_rb.html +101 -0
  13. data/doc/files/lib/libxslt_rb.html +110 -0
  14. data/doc/fr_class_index.html +29 -0
  15. data/doc/fr_file_index.html +34 -0
  16. data/doc/fr_method_index.html +28 -0
  17. data/doc/index.html +24 -0
  18. data/doc/rdoc-style.css +208 -0
  19. data/ext/libxslt/libxslt.c +21 -212
  20. data/ext/libxslt/libxslt.h +0 -17
  21. data/ext/libxslt/ruby_xslt_stylesheet.c +135 -173
  22. data/ext/libxslt/ruby_xslt_stylesheet.h +5 -10
  23. data/ext/libxslt/ruby_xslt_transform_context.c +5 -2
  24. data/ext/libxslt/version.h +2 -2
  25. data/lib/deprecated.rb +66 -0
  26. data/lib/libxslt.rb +1 -0
  27. data/mingw/libxslt_ruby.so +0 -0
  28. data/tests/files/commentary.dtd +34 -0
  29. data/tests/files/fuzface.xml +154 -0
  30. data/tests/files/fuzface.xsl +4 -0
  31. data/tests/files/params.xml +2 -0
  32. data/tests/files/params.xsl +11 -0
  33. data/tests/files/ramblings.xsl +46 -0
  34. data/tests/test_deprecated.rb +99 -0
  35. data/tests/test_libxslt.rb +21 -0
  36. data/tests/test_stylesheet.rb +64 -0
  37. data/tests/test_suite.rb +3 -0
  38. data/vc/libxslt_ruby.sln +1 -1
  39. data/vc/libxslt_ruby.vcproj +3 -3
  40. metadata +41 -10
  41. data/mingw/mingw.rake +0 -36
@@ -16,11 +16,6 @@
16
16
  #include <libxslt/xsltutils.h>
17
17
  #include <libexslt/exslt.h>
18
18
 
19
- // Includes from libxml-ruby
20
- #include <libxml/ruby_libxml.h>
21
- #include <libxml/ruby_xml_document.h>
22
-
23
-
24
19
  #include "ruby_xslt_stylesheet.h"
25
20
  #include "ruby_xslt_transform_context.h"
26
21
 
@@ -29,21 +24,9 @@
29
24
  #define RUBY_LIBXSLT_SRC_TYPE_NULL 0
30
25
  #define RUBY_LIBXSLT_SRC_TYPE_FILE 1
31
26
 
32
- extern VALUE mXML;
33
- //extern VALUE cXMLDocument;
34
-
35
27
  extern VALUE cXSLT;
36
28
  extern VALUE eXMLXSLTStylesheetRequireParsedDoc;
37
29
 
38
- typedef struct ruby_xslt {
39
- int data_type;
40
- void *data;
41
- VALUE str;
42
- VALUE xml_doc_obj;
43
- VALUE ctxt;
44
- xsltStylesheetPtr xsp;
45
- } ruby_xslt;
46
-
47
30
  #if ((RUBY_LIBXML_VER_MAJ != RUBY_LIBXSLT_VER_MAJ) || (RUBY_LIBXML_VER_MIN != RUBY_LIBXSLT_VER_MIN))
48
31
  #error "Incompatible LibXML-Ruby headers - please install same major/micro version"
49
32
  #endif
@@ -5,79 +5,144 @@
5
5
  #include "libxslt.h"
6
6
  #include "ruby_xslt_stylesheet.h"
7
7
 
8
- VALUE cXSLTStylesheet;
8
+ /*
9
+ * Document-class: XSLT::Stylesheet
10
+ *
11
+ * The XSLT::Stylesheet represents a XSL stylesheet that
12
+ * can be used to transform an XML document. For usage information
13
+ * refer to XSLT::Stylesheet#apply
14
+ *
15
+ */
9
16
 
10
- /* call-seq:
11
- * sheet.apply => (true|false)
12
- *
13
- * Apply this stylesheet transformation to the source
14
- * document.
15
- */
16
- VALUE
17
- ruby_xslt_stylesheet_apply(int argc, VALUE *argv, VALUE self) {
18
- ruby_xslt_stylesheet *xss;
19
- ruby_xml_document_t *rxd;
20
- const char **params;
21
- VALUE parameter, tmp;
22
- int i, len;
23
17
 
24
- Data_Get_Struct(self, ruby_xslt_stylesheet, xss);
25
-
26
- if (NIL_P(xss->xml_doc_obj))
27
- rb_raise(rb_eArgError, "Need a document object");
18
+ VALUE cXSLTStylesheet;
28
19
 
29
- Data_Get_Struct(xss->xml_doc_obj, ruby_xml_document_t, rxd);
20
+ VALUE
21
+ ruby_xslt_stylesheet_document_klass() {
22
+ VALUE mXML = rb_const_get(rb_cObject, rb_intern("XML"));
23
+ return rb_const_get(mXML, rb_intern("Document"));
24
+ }
30
25
 
31
- params = NULL;
32
26
 
33
- switch(argc) {
34
- case 0:
35
- break;
36
- case 1:
37
- parameter = argv[0];
38
- #if RUBY_VERSION_CODE >= 180
39
- if (TYPE(parameter) == T_HASH) {
40
- /* Convert parameter to an array */
41
- parameter = rb_hash_to_a(parameter);
42
- }
43
- #endif
44
-
45
- if (TYPE(parameter) == T_ARRAY) {
46
- /* A hash is better than an array, but we can live with an array of arrays */
47
- len = RARRAY(parameter)->len;
48
- params = (void *)ALLOC_N(char *, (len * 2) + 2);
49
- for (i=0; i < RARRAY(parameter)->len; i++) {
50
- tmp = RARRAY(parameter)->ptr[i];
27
+ void
28
+ ruby_xslt_stylesheet_free(xsltStylesheetPtr xstylesheet) {
29
+ xsltFreeStylesheet(xstylesheet);
30
+ }
51
31
 
52
- Check_Type(tmp, T_ARRAY);
53
- Check_Type(RARRAY(tmp)->ptr[0], T_STRING);
54
- Check_Type(RARRAY(tmp)->ptr[1], T_STRING);
32
+ VALUE
33
+ ruby_xslt_stylesheet_alloc(VALUE klass) {
34
+ return Data_Wrap_Struct(cXSLTStylesheet,
35
+ NULL, ruby_xslt_stylesheet_free,
36
+ NULL);
37
+ }
38
+
55
39
 
56
- params[2*i] = RSTRING(RARRAY(tmp)->ptr[0])->ptr;
57
- params[2*i+1] = RSTRING(RARRAY(tmp)->ptr[1])->ptr;
58
- }
59
- params[2*i] = params[2*i+1] = 0;
60
- } else {
61
- /* I should test to see if the object responds to to_a and to_h before calling this, but oh well */
62
- rb_raise(rb_eTypeError, "xslt_stylesheet_appy: expecting a hash or an array of arrays as a parameter");
63
- }
40
+ /* call-seq:
41
+ * XSLT::Stylesheet.new(document) -> XSLT::Stylesheet
42
+ *
43
+ * Creates a new XSLT stylesheet based on the provided document.
44
+ *
45
+ * stylesheet_doc = XML::Document.file('stylesheet_file')
46
+ * stylesheet = XSLT::Stylesheet.new(stylesheet_doc)
47
+ *
48
+ */
49
+ VALUE
50
+ ruby_xslt_stylesheet_initialize(VALUE self, VALUE document) {
51
+ ruby_xml_document_t *rdocument;
52
+
53
+ if (!rb_obj_is_kind_of(document, ruby_xslt_stylesheet_document_klass()))
54
+ rb_raise(rb_eTypeError, "Must pass in an XML::Document instance.");
55
+
56
+ Data_Get_Struct(document, ruby_xml_document_t, rdocument);
57
+ DATA_PTR(self) = xsltParseStylesheetDoc(rdocument->doc);
58
+ return self;
59
+ }
64
60
 
65
- break;
66
- default:
67
- rb_raise(rb_eArgError, "wrong number of arguments (0 or 1)");
61
+ /* Helper method to convert Ruby params to C params */
62
+ char **
63
+ ruby_xslt_coerce_params(VALUE params) {
64
+ char** result;
65
+ size_t length;
66
+ size_t i;
67
+
68
+ length = RARRAY(params)->len;
69
+ result = ALLOC_N(char *, length + 2);
70
+
71
+ for (i=0; i<length; i++) {
72
+ VALUE str = rb_String(RARRAY(params)->ptr[i]);
73
+ int strLen = RSTRING(str)->len;
74
+ result[i] = ALLOC_N(char, strLen + 1);
75
+ memset(result[i], 0, strLen + 1);
76
+ strncpy(result[i], RSTRING(str)->ptr, strLen);
68
77
  }
78
+
79
+ /* Null terminate the array - need to empty elements */
80
+ result[i] = NULL;
81
+ result[i+1] = NULL;
82
+
83
+ return result;
84
+ }
85
+
69
86
 
70
- xss->parsed = ruby_xml_document_wrap(xsltApplyStylesheet(xss->xsp,
71
- rxd->doc, params));
72
-
73
- if (params) {
74
- ruby_xfree(params);
87
+ /* call-seq:
88
+ * stylesheet.apply(document, {params}) -> XML::Document
89
+ *
90
+ * Apply this stylesheet transformation to the provided document.
91
+ * This method may be invoked multiple times.
92
+ *
93
+ * Params:
94
+ *
95
+ * document = An instance of an XML::Document
96
+ * params = An optional hash table that specifies the values
97
+ * for xsl:param values embedded in the stylesheet.
98
+ *
99
+ * Example:
100
+ *
101
+ * stylesheet_doc = XML::Document.file('stylesheet_file')
102
+ * stylesheet = XSLT::Stylesheet.new(stylesheet_doc)
103
+ *
104
+ * xml_doc = XML::Document.file('xml_file')
105
+ * result = stylesheet.apply(xml_doc)
106
+ * result = stylesheet.apply(xml_doc, {:foo => 'bar'})
107
+ */
108
+ VALUE
109
+ ruby_xslt_stylesheet_apply(int argc, VALUE *argv, VALUE self) {
110
+ ruby_xml_document_t *rdocument;
111
+ xsltStylesheetPtr xstylesheet;
112
+ xmlDocPtr result;
113
+ VALUE document;
114
+ VALUE params;
115
+ int i;
116
+
117
+ char** pParams;
118
+
119
+ if (argc > 2 || argc < 1)
120
+ rb_raise(rb_eArgError, "wrong number of arguments (need 1 or 2)");
121
+
122
+ document = argv[0];
123
+
124
+ if (!rb_obj_is_kind_of(document, ruby_xslt_stylesheet_document_klass()))
125
+ rb_raise(rb_eTypeError, "Must pass in an XML::Document instance.");
126
+
127
+ /* Make sure params is a flat array */
128
+ params = (argc == 2 ? argv[1]: Qnil);
129
+ params = rb_Array(params);
130
+ rb_funcall(params, rb_intern("flatten!"), 0);
131
+ pParams = ruby_xslt_coerce_params(params);
132
+
133
+ Data_Get_Struct(document, ruby_xml_document_t, rdocument);
134
+ Data_Get_Struct(self, xsltStylesheet, xstylesheet);
135
+
136
+ result = xsltApplyStylesheet(xstylesheet, rdocument->doc, pParams);
137
+
138
+ /* Free allocated array of *chars. Note we don't have to
139
+ free the last array item since its set to NULL. */
140
+ for (i=0; i<(RARRAY(params)->len); i++) {
141
+ ruby_xfree(pParams[i]);
75
142
  }
76
-
77
- if (xss->parsed == Qnil)
78
- return(Qfalse);
79
- else
80
- return(Qtrue);
143
+ ruby_xfree(pParams);
144
+
145
+ return ruby_xml_document_wrap(result);
81
146
  }
82
147
 
83
148
 
@@ -90,7 +155,7 @@ ruby_xslt_stylesheet_apply(int argc, VALUE *argv, VALUE self) {
90
155
  * is not the case, a warning is triggered and the method returns
91
156
  * false.
92
157
  */
93
- VALUE
158
+ /*VALUE
94
159
  ruby_xslt_stylesheet_debug(int argc, VALUE *argv, VALUE self) {
95
160
  #ifdef LIBXML_DEBUG_ENABLED
96
161
  OpenFile *fptr;
@@ -130,48 +195,7 @@ ruby_xslt_stylesheet_debug(int argc, VALUE *argv, VALUE self) {
130
195
  return(Qfalse);
131
196
  #endif
132
197
  }
133
-
134
-
135
- void
136
- ruby_xslt_stylesheet_free(ruby_xslt_stylesheet *xss) {
137
- if (xss->xsp != NULL) {
138
- xsltFreeStylesheet(xss->xsp);
139
- xss->xsp = NULL;
140
- }
141
-
142
- ruby_xfree(xss);
143
- }
144
-
145
-
146
- void
147
- ruby_xslt_stylesheet_mark(ruby_xslt_stylesheet *xss) {
148
- if (!NIL_P(xss->parsed)) rb_gc_mark(xss->parsed);
149
- if (!NIL_P(xss->xml_doc_obj)) rb_gc_mark(xss->xml_doc_obj);
150
-
151
- switch (xss->data_type) {
152
- case RUBY_LIBXSLT_SRC_TYPE_FILE:
153
- if (xss->data != NULL)
154
- rb_gc_mark((VALUE)xss->data);
155
- break;
156
- }
157
- }
158
-
159
-
160
- VALUE
161
- ruby_xslt_stylesheet_new(VALUE class, xsltStylesheetPtr xsp) {
162
- ruby_xslt_stylesheet *xss;
163
- VALUE rval;
164
-
165
- rval=Data_Make_Struct(cXSLTStylesheet,ruby_xslt_stylesheet,ruby_xslt_stylesheet_mark,
166
- ruby_xslt_stylesheet_free,xss);
167
- xss->xsp = xsp;
168
- xss->xml_doc_obj = Qnil;
169
- xss->parsed = Qnil;
170
- xss->data_type = RUBY_LIBXSLT_SRC_TYPE_NULL;
171
- xss->data = NULL;
172
-
173
- return rval;
174
- }
198
+ */
175
199
 
176
200
  // TODO should this automatically apply the sheet if not already,
177
201
  // given that we're unlikely to do much else with it?
@@ -183,7 +207,7 @@ ruby_xslt_stylesheet_new(VALUE class, xsltStylesheetPtr xsp) {
183
207
  * stream (an IO instance, defaults to $stdout). You *must* call
184
208
  * +apply+ before this method or an exception will be raised.
185
209
  */
186
- VALUE
210
+ /*VALUE
187
211
  ruby_xslt_stylesheet_print(int argc, VALUE *argv, VALUE self) {
188
212
  OpenFile *fptr;
189
213
  VALUE io;
@@ -219,80 +243,18 @@ ruby_xslt_stylesheet_print(int argc, VALUE *argv, VALUE self) {
219
243
  bytes = xsltSaveResultToFile(out, parsed->doc, xss->xsp);
220
244
 
221
245
  return(INT2NUM(bytes));
222
- }
223
-
224
- // TODO this, too. Either way, to_s probably should have prereqs
225
- // like this, for one thing it makes IRB use tricky...
226
-
227
- /* call-seq:
228
- * sheet.to_s => "result"
229
- *
230
- * Obtain the result of the transform as a string. You *must* call
231
- * +apply+ before this method or an exception will be raised.
232
- */
233
- VALUE
234
- ruby_xslt_stylesheet_to_s(VALUE self) {
235
- ruby_xml_document_t *parsed;
236
- ruby_xslt_stylesheet *xss;
237
- xmlChar *str;
238
- int len;
239
-
240
- Data_Get_Struct(self, ruby_xslt_stylesheet, xss);
241
- if (NIL_P(xss->parsed))
242
- rb_raise(eXMLXSLTStylesheetRequireParsedDoc, "must have a parsed XML result");
243
- Data_Get_Struct(xss->parsed, ruby_xml_document_t, parsed);
244
- if (parsed->doc == NULL)
245
- return(Qnil);
246
-
247
- xsltSaveResultToString(&str, &len, parsed->doc, xss->xsp);
248
- if (str == NULL)
249
- return(Qnil);
250
- else
251
- return(rb_str_new((const char*)str,len));
252
- }
246
+ }*/
253
247
 
254
248
 
255
-
256
- /* call-seq:
257
- * sheet.save(io) => true
258
- *
259
- * Save the result of the transform to the supplied open
260
- * file (an IO instance). You *must* call +apply+ before
261
- * this method or an exception will be raised.
262
- */
263
- VALUE
264
- ruby_xslt_stylesheet_save(VALUE self, VALUE io) {
265
- ruby_xml_document_t *parsed;
266
- ruby_xslt_stylesheet *xss;
267
- OpenFile *fptr;
268
-
269
- if (rb_obj_is_kind_of(io, rb_cIO) == Qfalse)
270
- rb_raise(rb_eArgError, "Only accept IO objects for saving");
271
-
272
- GetOpenFile(io, fptr);
273
-
274
- Data_Get_Struct(self, ruby_xslt_stylesheet, xss);
275
- Data_Get_Struct(xss->parsed, ruby_xml_document_t, parsed);
276
-
277
- xsltSaveResultToFile(fptr->f, parsed->doc, xss->xsp);
278
-
279
- return(Qtrue);
280
- }
281
-
282
249
  #ifdef RDOC_NEVER_DEFINED
283
- mXML = rb_define_module("XML");
284
- cXSLT = rb_define_class_under(mXML, "XSLT", rb_cObject);
250
+ cXSLT = rb_define_module("XSLT");
251
+ cXSLTStylesheet = rb_define_class_under(cXSLT, "Stylesheet", rb_cObject);
285
252
  #endif
286
253
 
287
254
  void
288
255
  ruby_init_xslt_stylesheet(void) {
289
256
  cXSLTStylesheet = rb_define_class_under(cXSLT, "Stylesheet", rb_cObject);
290
- eXMLXSLTStylesheetRequireParsedDoc =
291
- rb_define_class_under(cXSLTStylesheet, "RequireParsedDoc", rb_eException);
292
-
257
+ rb_define_alloc_func(cXSLTStylesheet, ruby_xslt_stylesheet_alloc);
258
+ rb_define_method(cXSLTStylesheet, "initialize", ruby_xslt_stylesheet_initialize, 1);
293
259
  rb_define_method(cXSLTStylesheet, "apply", ruby_xslt_stylesheet_apply, -1);
294
- rb_define_method(cXSLTStylesheet, "debug", ruby_xslt_stylesheet_debug, -1);
295
- rb_define_method(cXSLTStylesheet, "print", ruby_xslt_stylesheet_print, -1);
296
- rb_define_method(cXSLTStylesheet, "to_s", ruby_xslt_stylesheet_to_s, 0);
297
- rb_define_method(cXSLTStylesheet, "save", ruby_xslt_stylesheet_save, 1);
298
260
  }
@@ -5,17 +5,12 @@
5
5
  #ifndef __RUBY_LIBXSLT_STYLESHEET__
6
6
  #define __RUBY_LIBXSLT_STYLESHEET__
7
7
 
8
- extern VALUE cXSLTStylesheet;
8
+ // Includes from libxml-ruby
9
+ #include <libxml/ruby_libxml.h>
10
+ #include <libxml/ruby_xml_document.h>
9
11
 
10
- typedef struct ruby_xslt_stylesheet {
11
- int data_type;
12
- void *data;
13
- VALUE parsed; /* XML::Document # parsed xml document after xsl apply */
14
- VALUE xml_doc_obj; /* XML::Document */
15
- xsltStylesheetPtr xsp;
16
- } ruby_xslt_stylesheet;
12
+ extern VALUE cXSLTStylesheet;
17
13
 
18
14
  void ruby_init_xslt_stylesheet(void);
19
- VALUE ruby_xslt_stylesheet_new(VALUE class, xsltStylesheetPtr xsp);
20
15
 
21
- #endif /* __RUBY_LIBXSLT_STYLESHEET__ */
16
+ #endif
@@ -5,6 +5,9 @@
5
5
  #include "libxslt.h"
6
6
  #include "ruby_xslt_transform_context.h"
7
7
 
8
+
9
+ /* :nodoc: */
10
+
8
11
  VALUE cXSLTTransformContext;
9
12
 
10
13
  void
@@ -50,8 +53,8 @@ ruby_xslt_transform_context_new3(VALUE xslt) {
50
53
  }
51
54
 
52
55
  #ifdef RDOC_NEVER_DEFINED
53
- mXML = rb_define_module("XML");
54
- cXSLT = rb_define_class_under(mXML, "XSLT", rb_cObject);
56
+ cXSLT = rb_define_module("XSLT");
57
+ cXSLTTransformContext = rb_define_class_under(cXSLT, "TransformContext", rb_cObject);
55
58
  #endif
56
59
 
57
60
  void
@@ -1,5 +1,5 @@
1
- #define RUBY_LIBXSLT_VERSION "0.6.0"
1
+ #define RUBY_LIBXSLT_VERSION "0.7.0"
2
2
  #define RUBY_LIBXSLT_VERNUM 0
3
3
  #define RUBY_LIBXSLT_VER_MAJ 0
4
- #define RUBY_LIBXSLT_VER_MIN 6
4
+ #define RUBY_LIBXSLT_VER_MIN 7
5
5
  #define RUBY_LIBXSLT_VER_MIC 0
data/lib/deprecated.rb ADDED
@@ -0,0 +1,66 @@
1
+ # :enddoc:
2
+ # These classes provide provide backwards compatibility with
3
+ # versions of libxslt-ruby prior to version 0.7.0
4
+
5
+ module XML
6
+ module XSLT
7
+ MAX_DEPTH = ::XSLT::MAX_DEPTH
8
+ MAX_SORT = ::XSLT::MAX_SORT
9
+ ENGINE_VERSION = ::XSLT::ENGINE_VERSION
10
+ LIBXSLT_VERSION = ::XSLT::LIBXSLT_VERSION
11
+ LIBXML_VERSION = ::XSLT::LIBXML_VERSION
12
+ XSLT_NAMESPACE = ::XSLT::XSLT_NAMESPACE
13
+ DEFAULT_VENDOR = ::XSLT::DEFAULT_VENDOR
14
+ DEFAULT_VERSION = ::XSLT::DEFAULT_VERSION
15
+ DEFAULT_URL = ::XSLT::DEFAULT_URL
16
+ NAMESPACE_LIBXSLT = ::XSLT::NAMESPACE_LIBXSLT
17
+ NAMESPACE_NORM_SAXON = ::XSLT::NAMESPACE_NORM_SAXON
18
+ NAMESPACE_SAXON = ::XSLT::NAMESPACE_SAXON
19
+ NAMESPACE_XT = ::XSLT::NAMESPACE_XT
20
+ NAMESPACE_XALAN = ::XSLT::NAMESPACE_XALAN
21
+
22
+ def self.new
23
+ Stylesheet.new(nil)
24
+ end
25
+
26
+ def self.file(filename)
27
+ doc = Document.file(filename)
28
+ stylesheet = ::XSLT::Stylesheet.new(doc)
29
+
30
+ result = Stylesheet.new(stylesheet)
31
+ result.filename = filename
32
+ result
33
+ end
34
+
35
+ class Stylesheet
36
+ attr_accessor :doc, :filename
37
+
38
+ def initialize(stylesheet)
39
+ @stylesheet = stylesheet
40
+ end
41
+
42
+ def filename=(value)
43
+ @doc = Document.file(value)
44
+ @filename = value
45
+ end
46
+
47
+ def parse
48
+ self
49
+ end
50
+
51
+ def apply
52
+ @result = @stylesheet.apply(@doc)
53
+ end
54
+
55
+ def save(filename)
56
+ raise(ArgumentError) unless @result
57
+ @result.save(filename)
58
+ end
59
+
60
+ def print(filename)
61
+ raise(ArgumentError) unless @result
62
+ end
63
+ end
64
+ end
65
+ end
66
+