libxslt-ruby 1.0.1-x86-mingw32 → 1.0.2-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +37 -7
- data/LICENSE +7 -7
- data/{README → README.rdoc} +19 -19
- data/Rakefile +25 -9
- data/ext/libxslt/extconf.h +8 -8
- data/ext/libxslt/extconf.rb +33 -22
- data/ext/libxslt/libxslt.c +7 -8
- data/ext/libxslt/libxslt.h +10 -0
- data/ext/libxslt/ruby_exslt.c +148 -0
- data/ext/libxslt/ruby_exslt.h +8 -0
- data/ext/libxslt/ruby_xslt_stylesheet.c +37 -45
- data/ext/libxslt/ruby_xslt_stylesheet.h +0 -4
- data/ext/libxslt/version.h +2 -2
- data/lib/1.8/libxslt_ruby.so +0 -0
- data/lib/1.9/libxslt_ruby.so +0 -0
- data/lib/libxslt/deprecated.rb +2 -2
- data/lib/xslt.rb +1 -1
- data/libxslt-ruby.gemspec +9 -9
- data/setup.rb +1585 -1585
- data/test/test_deprecated.rb +16 -14
- data/test/test_exslt.rb +70 -0
- data/test/test_helper.rb +16 -12
- data/test/test_stylesheet.rb +22 -22
- data/test/test_suite.rb +2 -1
- metadata +28 -10
- data/test/text.xml +0 -134
data/ext/libxslt/libxslt.h
CHANGED
@@ -6,17 +6,26 @@
|
|
6
6
|
#define __RUBY_LIBXSLT_H__
|
7
7
|
|
8
8
|
#include <ruby.h>
|
9
|
+
#if HAVE_RUBY_IO_H
|
10
|
+
#include <ruby/io.h>
|
11
|
+
#else
|
9
12
|
#include <rubyio.h>
|
13
|
+
#endif
|
14
|
+
|
10
15
|
#include <libxml/parser.h>
|
11
16
|
#include <libxml/debugXML.h>
|
17
|
+
#include <ruby_libxml.h>
|
18
|
+
|
12
19
|
#include <libxslt/extra.h>
|
13
20
|
#include <libxslt/xslt.h>
|
14
21
|
#include <libxslt/xsltInternals.h>
|
15
22
|
#include <libxslt/transform.h>
|
16
23
|
#include <libxslt/xsltutils.h>
|
24
|
+
|
17
25
|
#include <libexslt/exslt.h>
|
18
26
|
|
19
27
|
#include "ruby_xslt_stylesheet.h"
|
28
|
+
#include "ruby_exslt.h"
|
20
29
|
|
21
30
|
#include "version.h"
|
22
31
|
|
@@ -27,5 +36,6 @@
|
|
27
36
|
extern VALUE cLibXSLT;
|
28
37
|
extern VALUE cXSLT;
|
29
38
|
extern VALUE eXSLTError;
|
39
|
+
extern VALUE cXMLDocument;
|
30
40
|
|
31
41
|
#endif
|
@@ -0,0 +1,148 @@
|
|
1
|
+
/* http://xmlsoft.org/XSLT/html/libxslt-extensions.html */
|
2
|
+
|
3
|
+
#include "libxslt.h"
|
4
|
+
|
5
|
+
/* Helper method to retrieve (and possibly initialize)
|
6
|
+
the module function registry hash for +namespace+ */
|
7
|
+
static VALUE
|
8
|
+
ruby_xslt_module_function_hash(VALUE namespace) {
|
9
|
+
VALUE ns_hash, func_hash;
|
10
|
+
|
11
|
+
if ((ns_hash = rb_ivar_get(cXSLT, rb_intern("@module_function_registry"))) == Qnil) {
|
12
|
+
ns_hash = rb_ivar_set(cXSLT, rb_intern("@module_function_registry"), rb_hash_new());
|
13
|
+
}
|
14
|
+
|
15
|
+
if ((func_hash = rb_hash_aref(ns_hash, namespace)) == Qnil) {
|
16
|
+
func_hash = rb_hash_aset(ns_hash, namespace, rb_hash_new());
|
17
|
+
}
|
18
|
+
|
19
|
+
return func_hash;
|
20
|
+
}
|
21
|
+
|
22
|
+
/* Helper method for xsltRegisterExtModuleFunction callback */
|
23
|
+
static void
|
24
|
+
ruby_xslt_module_function_callback(xmlXPathParserContextPtr ctxt, int nargs) {
|
25
|
+
VALUE callback, args[nargs];
|
26
|
+
const xmlChar *namespace, *name;
|
27
|
+
int i;
|
28
|
+
|
29
|
+
if (ctxt == NULL || ctxt->context == NULL) {
|
30
|
+
return;
|
31
|
+
}
|
32
|
+
|
33
|
+
namespace = ctxt->context->functionURI;
|
34
|
+
name = ctxt->context->function;
|
35
|
+
|
36
|
+
callback = rb_hash_aref(
|
37
|
+
ruby_xslt_module_function_hash(rb_str_new2((char *)namespace)),
|
38
|
+
rb_str_new2((char *)name)
|
39
|
+
);
|
40
|
+
|
41
|
+
if (callback == Qnil) {
|
42
|
+
rb_raise(rb_eArgError, "name `%s' not registered", name);
|
43
|
+
}
|
44
|
+
|
45
|
+
for (i = nargs - 1; i >= 0; i--) {
|
46
|
+
args[i] = rxml_xpath_to_value(ctxt->context, valuePop(ctxt));
|
47
|
+
}
|
48
|
+
|
49
|
+
valuePush(ctxt, rxml_xpath_from_value(
|
50
|
+
rb_funcall2(callback, rb_intern("call"), nargs, args)
|
51
|
+
));
|
52
|
+
}
|
53
|
+
|
54
|
+
/* call-seq:
|
55
|
+
* XSLT.register_module_function(namespace, name) { ... } -> Proc or nil
|
56
|
+
*
|
57
|
+
* Registers +name+ as extension module function in +namespace+ with the
|
58
|
+
* block as callback. Returns the callback if successful, or +nil+ otherwise.
|
59
|
+
*
|
60
|
+
* The callback will be called with whatever XPath expression you pass
|
61
|
+
* into the function converted to a Ruby object. Its return value will
|
62
|
+
* be converted to an XPath expression again.
|
63
|
+
*
|
64
|
+
* Example:
|
65
|
+
*
|
66
|
+
* # register your extension function
|
67
|
+
* XSLT.register_module_function('http://ex.ns', 'ex-func') { |xp|
|
68
|
+
* xp.to_a.join('|').upcase
|
69
|
+
* }
|
70
|
+
*
|
71
|
+
* # then use it in your stylesheet
|
72
|
+
* <xsl:stylesheet ... xmlns:ex="http://ex.ns">
|
73
|
+
* ...
|
74
|
+
* <xsl:value-of select="ex:ex-func(.)" />
|
75
|
+
* <!-- the current node as upper case string -->
|
76
|
+
* </xsl:stylesheet>
|
77
|
+
*/
|
78
|
+
static VALUE
|
79
|
+
ruby_xslt_register_module_function(VALUE class, VALUE namespace, VALUE name) {
|
80
|
+
VALUE callback;
|
81
|
+
|
82
|
+
if (!rb_block_given_p()) {
|
83
|
+
rb_raise(rb_eArgError, "no block given");
|
84
|
+
}
|
85
|
+
|
86
|
+
if (xsltRegisterExtModuleFunction(
|
87
|
+
BAD_CAST StringValuePtr(name),
|
88
|
+
BAD_CAST StringValuePtr(namespace),
|
89
|
+
ruby_xslt_module_function_callback
|
90
|
+
) != 0) {
|
91
|
+
return Qnil;
|
92
|
+
}
|
93
|
+
|
94
|
+
callback = rb_block_proc();
|
95
|
+
|
96
|
+
rb_hash_aset(ruby_xslt_module_function_hash(namespace), name, callback);
|
97
|
+
return callback;
|
98
|
+
}
|
99
|
+
|
100
|
+
/* call-seq:
|
101
|
+
* XSLT.unregister_module_function(namespace, name) -> Proc or nil
|
102
|
+
*
|
103
|
+
* Unregisters +name+ as extension module function in +namespace+.
|
104
|
+
* Returns the previous callback if successful, or +nil+ otherwise.
|
105
|
+
*/
|
106
|
+
static VALUE
|
107
|
+
ruby_xslt_unregister_module_function(VALUE class, VALUE namespace, VALUE name) {
|
108
|
+
VALUE func_hash, callback;
|
109
|
+
|
110
|
+
func_hash = ruby_xslt_module_function_hash(namespace);
|
111
|
+
|
112
|
+
if ((callback = rb_hash_aref(func_hash, name)) == Qnil) {
|
113
|
+
return Qnil;
|
114
|
+
}
|
115
|
+
|
116
|
+
if (xsltUnregisterExtModuleFunction(
|
117
|
+
BAD_CAST StringValuePtr(name),
|
118
|
+
BAD_CAST StringValuePtr(namespace)
|
119
|
+
) != 0) {
|
120
|
+
return Qnil;
|
121
|
+
}
|
122
|
+
|
123
|
+
rb_hash_aset(func_hash, name, Qnil);
|
124
|
+
return callback;
|
125
|
+
}
|
126
|
+
|
127
|
+
/* call-seq:
|
128
|
+
* XSLT.registered_module_function?(namespace, name) -> true or false
|
129
|
+
*
|
130
|
+
* Returns +true+ if +name+ is currently registered as extension module
|
131
|
+
* function in +namespace+, or +false+ otherwise.
|
132
|
+
*/
|
133
|
+
static VALUE
|
134
|
+
ruby_xslt_registered_module_function_p(VALUE class, VALUE namespace, VALUE name) {
|
135
|
+
return RTEST(rb_hash_aref(ruby_xslt_module_function_hash(namespace), name));
|
136
|
+
}
|
137
|
+
|
138
|
+
void
|
139
|
+
ruby_init_exslt() {
|
140
|
+
/* [HACK] Enclosing classes/modules for RDoc:
|
141
|
+
* cLibXSLT = rb_define_module("LibXSLT");
|
142
|
+
* cXSLT = rb_define_module_under(cLibXSLT, "XSLT");
|
143
|
+
*/
|
144
|
+
|
145
|
+
rb_define_singleton_method(cXSLT, "register_module_function", ruby_xslt_register_module_function, 2);
|
146
|
+
rb_define_singleton_method(cXSLT, "unregister_module_function", ruby_xslt_unregister_module_function, 2);
|
147
|
+
rb_define_singleton_method(cXSLT, "registered_module_function?", ruby_xslt_registered_module_function_p, 2);
|
148
|
+
}
|
@@ -3,25 +3,18 @@
|
|
3
3
|
/* See the LICENSE file for copyright and distribution information. */
|
4
4
|
|
5
5
|
#include "libxslt.h"
|
6
|
-
#include "ruby_xslt_stylesheet.h"
|
7
6
|
|
8
7
|
/*
|
9
8
|
* Document-class: LibXSLT::XSLT::Stylesheet
|
10
|
-
*
|
9
|
+
*
|
11
10
|
* The XSLT::Stylesheet represents a XSL stylesheet that
|
12
11
|
* can be used to transform an XML document. For usage information
|
13
12
|
* refer to XSLT::Stylesheet#apply
|
14
13
|
*
|
15
|
-
*/
|
14
|
+
*/
|
16
15
|
|
17
16
|
VALUE cXSLTStylesheet;
|
18
17
|
|
19
|
-
static VALUE
|
20
|
-
ruby_xslt_stylesheet_document_klass() {
|
21
|
-
VALUE mXML = rb_const_get(rb_cObject, rb_intern("XML"));
|
22
|
-
return rb_const_get(mXML, rb_intern("Document"));
|
23
|
-
}
|
24
|
-
|
25
18
|
void
|
26
19
|
ruby_xslt_stylesheet_free(xsltStylesheetPtr xstylesheet) {
|
27
20
|
xsltFreeStylesheet(xstylesheet);
|
@@ -33,11 +26,11 @@ ruby_xslt_stylesheet_alloc(VALUE klass) {
|
|
33
26
|
NULL, ruby_xslt_stylesheet_free,
|
34
27
|
NULL);
|
35
28
|
}
|
36
|
-
|
29
|
+
|
37
30
|
|
38
31
|
/* call-seq:
|
39
32
|
* XSLT::Stylesheet.new(document) -> XSLT::Stylesheet
|
40
|
-
*
|
33
|
+
*
|
41
34
|
* Creates a new XSLT stylesheet based on the specified document.
|
42
35
|
* For memory management reasons, a copy of the specified document
|
43
36
|
* will be made, so its best to create a single copy of a stylesheet
|
@@ -53,24 +46,24 @@ ruby_xslt_stylesheet_initialize(VALUE self, VALUE document) {
|
|
53
46
|
xmlDocPtr xcopy;
|
54
47
|
xsltStylesheetPtr xstylesheet;
|
55
48
|
|
56
|
-
if (!rb_obj_is_kind_of(document,
|
49
|
+
if (!rb_obj_is_kind_of(document, cXMLDocument))
|
57
50
|
rb_raise(rb_eTypeError, "Must pass in an XML::Document instance.");
|
58
|
-
|
59
|
-
/* NOTE!! Since the stylesheet own the specified document, the easiest
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
51
|
+
|
52
|
+
/* NOTE!! Since the stylesheet own the specified document, the easiest
|
53
|
+
* thing to do from a memory standpoint is too copy it and not expose
|
54
|
+
* the copy to Ruby. The other solution is expose a memory management
|
55
|
+
* API on the document object for taking ownership of the document
|
56
|
+
* and specifying when it has been freed. Then the document class
|
57
|
+
* has to be updated to always check and see if the document is
|
58
|
+
* still valid. That's all doable, but seems like a pain, so
|
59
|
+
* just copy the document for now. */
|
67
60
|
Data_Get_Struct(document, xmlDoc, xdoc);
|
68
61
|
xcopy = xmlCopyDoc(xdoc, 1);
|
69
62
|
xstylesheet = xsltParseStylesheetDoc(xcopy);
|
70
63
|
xstylesheet->_private = (void *)self;
|
71
64
|
DATA_PTR(self) = xstylesheet;
|
72
|
-
|
73
|
-
/* Save a reference to the document as an attribute accessable to ruby*/
|
65
|
+
|
66
|
+
/* Save a reference to the document as an attribute accessable to ruby */
|
74
67
|
return self;
|
75
68
|
}
|
76
69
|
|
@@ -91,18 +84,17 @@ ruby_xslt_coerce_params(VALUE params) {
|
|
91
84
|
memset(result[i], 0, strLen + 1);
|
92
85
|
strncpy(result[i], RSTRING_PTR(str), strLen);
|
93
86
|
}
|
94
|
-
|
87
|
+
|
95
88
|
/* Null terminate the array - need to empty elements */
|
96
89
|
result[i] = NULL;
|
97
90
|
result[i+1] = NULL;
|
98
|
-
|
91
|
+
|
99
92
|
return result;
|
100
|
-
}
|
101
|
-
|
93
|
+
}
|
102
94
|
|
103
|
-
/* call-seq:
|
95
|
+
/* call-seq:
|
104
96
|
* stylesheet.apply(document, {params}) -> XML::Document
|
105
|
-
*
|
97
|
+
*
|
106
98
|
* Apply this stylesheet transformation to the provided document.
|
107
99
|
* This method may be invoked multiple times.
|
108
100
|
*
|
@@ -111,7 +103,7 @@ ruby_xslt_coerce_params(VALUE params) {
|
|
111
103
|
* * params - An optional hash table that specifies the values for xsl:param values embedded in the stylesheet.
|
112
104
|
*
|
113
105
|
* Example:
|
114
|
-
*
|
106
|
+
*
|
115
107
|
* stylesheet_doc = XML::Document.file('stylesheet_file')
|
116
108
|
* stylesheet = XSLT::Stylesheet.new(stylesheet_doc)
|
117
109
|
*
|
@@ -127,15 +119,15 @@ ruby_xslt_stylesheet_apply(int argc, VALUE *argv, VALUE self) {
|
|
127
119
|
VALUE document;
|
128
120
|
VALUE params;
|
129
121
|
int i;
|
130
|
-
|
122
|
+
|
131
123
|
char** pParams;
|
132
124
|
|
133
125
|
if (argc > 2 || argc < 1)
|
134
126
|
rb_raise(rb_eArgError, "wrong number of arguments (need 1 or 2)");
|
135
|
-
|
127
|
+
|
136
128
|
document = argv[0];
|
137
|
-
|
138
|
-
if (!rb_obj_is_kind_of(document,
|
129
|
+
|
130
|
+
if (!rb_obj_is_kind_of(document, cXMLDocument))
|
139
131
|
rb_raise(rb_eTypeError, "Must pass in an XML::Document instance.");
|
140
132
|
|
141
133
|
/* Make sure params is a flat array */
|
@@ -143,29 +135,29 @@ ruby_xslt_stylesheet_apply(int argc, VALUE *argv, VALUE self) {
|
|
143
135
|
params = rb_Array(params);
|
144
136
|
rb_funcall(params, rb_intern("flatten!"), 0);
|
145
137
|
pParams = ruby_xslt_coerce_params(params);
|
146
|
-
|
138
|
+
|
147
139
|
Data_Get_Struct(document, xmlDoc, xdoc);
|
148
140
|
Data_Get_Struct(self, xsltStylesheet, xstylesheet);
|
149
|
-
|
141
|
+
|
150
142
|
result = xsltApplyStylesheet(xstylesheet, xdoc, (const char**)pParams);
|
151
|
-
|
143
|
+
|
152
144
|
if (!result)
|
153
145
|
rb_raise(eXSLTError, "Transformation failed");
|
154
|
-
|
146
|
+
|
155
147
|
/* Free allocated array of *chars. Note we don't have to
|
156
148
|
free the last array item since its set to NULL. */
|
157
149
|
for (i=0; i<RARRAY_LEN(params); i++) {
|
158
150
|
ruby_xfree(pParams[i]);
|
159
151
|
}
|
160
152
|
ruby_xfree(pParams);
|
161
|
-
|
153
|
+
|
162
154
|
return rxml_document_wrap(result);
|
163
155
|
}
|
164
156
|
|
165
157
|
|
166
|
-
/* call-seq:
|
158
|
+
/* call-seq:
|
167
159
|
* sheet.debug(to = $stdout) => (true|false)
|
168
|
-
*
|
160
|
+
*
|
169
161
|
* Output a debug dump of this stylesheet to the specified output
|
170
162
|
* stream (an instance of IO, defaults to $stdout). Requires
|
171
163
|
* libxml/libxslt be compiled with debugging enabled. If this
|
@@ -214,12 +206,12 @@ ruby_xslt_stylesheet_debug(int argc, VALUE *argv, VALUE self) {
|
|
214
206
|
}
|
215
207
|
*/
|
216
208
|
|
217
|
-
|
218
|
-
|
209
|
+
/* TODO should this automatically apply the sheet if not already,
|
210
|
+
given that we're unlikely to do much else with it? */
|
219
211
|
|
220
|
-
/* call-seq:
|
212
|
+
/* call-seq:
|
221
213
|
* sheet.print(to = $stdout) => number_of_bytes
|
222
|
-
*
|
214
|
+
*
|
223
215
|
* Output the result of the transform to the specified output
|
224
216
|
* stream (an IO instance, defaults to $stdout). You *must* call
|
225
217
|
* +apply+ before this method or an exception will be raised.
|
@@ -5,10 +5,6 @@
|
|
5
5
|
#ifndef __RUBY_LIBXSLT_STYLESHEET__
|
6
6
|
#define __RUBY_LIBXSLT_STYLESHEET__
|
7
7
|
|
8
|
-
// Includes from libxml-ruby
|
9
|
-
#include <libxml/ruby_libxml.h>
|
10
|
-
#include <libxml/ruby_xml_document.h>
|
11
|
-
|
12
8
|
extern VALUE cXSLTStylesheet;
|
13
9
|
|
14
10
|
void ruby_init_xslt_stylesheet(void);
|
data/ext/libxslt/version.h
CHANGED
data/lib/1.8/libxslt_ruby.so
CHANGED
Binary file
|
data/lib/1.9/libxslt_ruby.so
CHANGED
Binary file
|
data/lib/libxslt/deprecated.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
# :enddoc:
|
3
|
-
# These classes provide provide backwards compatibility with
|
3
|
+
# These classes provide provide backwards compatibility with
|
4
4
|
# versions of libxslt-ruby prior to version 0.7.0
|
5
5
|
|
6
6
|
module LibXML
|
7
7
|
module XML
|
8
|
-
module XSLT
|
8
|
+
module XSLT
|
9
9
|
MAX_DEPTH = LibXSLT::XSLT::MAX_DEPTH
|
10
10
|
MAX_SORT = LibXSLT::XSLT::MAX_SORT
|
11
11
|
ENGINE_VERSION = LibXSLT::XSLT::ENGINE_VERSION
|
data/lib/xslt.rb
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
# It is recommend that you only load this file for libs
|
6
6
|
# that do not have their own namespace, eg. administrative
|
7
7
|
# scripts, personal programs, etc. For other applications
|
8
|
-
# require 'libxslt' instead and include LibXSLT into your
|
8
|
+
# require 'libxslt' instead and include LibXSLT into your
|
9
9
|
# app/libs namespace.
|
10
10
|
|
11
11
|
require 'libxslt'
|
data/libxslt-ruby.gemspec
CHANGED
@@ -7,7 +7,7 @@ FILES = FileList[
|
|
7
7
|
'CHANGES',
|
8
8
|
'LICENSE',
|
9
9
|
'Rakefile',
|
10
|
-
'README',
|
10
|
+
'README.rdoc',
|
11
11
|
'libxslt-ruby.gemspec',
|
12
12
|
'setup.rb',
|
13
13
|
'doc/**/*',
|
@@ -22,11 +22,11 @@ FILES = FileList[
|
|
22
22
|
# Default GEM Specification
|
23
23
|
Gem::Specification.new do |spec|
|
24
24
|
spec.name = "libxslt-ruby"
|
25
|
-
|
25
|
+
|
26
26
|
spec.homepage = "http://libxslt.rubyforge.org/"
|
27
27
|
spec.summary = "Ruby libxslt bindings"
|
28
28
|
spec.description = <<-EOF
|
29
|
-
The Libxslt-Ruby project provides Ruby language bindings for the GNOME
|
29
|
+
The Libxslt-Ruby project provides Ruby language bindings for the GNOME
|
30
30
|
XSLT C library. It is free software, released under the MIT License.
|
31
31
|
EOF
|
32
32
|
|
@@ -34,16 +34,16 @@ Gem::Specification.new do |spec|
|
|
34
34
|
spec.version = version
|
35
35
|
spec.author = "Charlie Savage"
|
36
36
|
spec.email = "libxml-devel@rubyforge.org"
|
37
|
-
spec.add_dependency('libxml-ruby','>=2.
|
37
|
+
spec.add_dependency('libxml-ruby','>=2.1.1')
|
38
38
|
spec.platform = Gem::Platform::RUBY
|
39
|
-
spec.require_paths = ["lib", "ext/libxslt"]
|
40
|
-
|
39
|
+
spec.require_paths = ["lib", "ext/libxslt"]
|
40
|
+
|
41
41
|
spec.bindir = "bin"
|
42
42
|
spec.extensions = ["ext/libxslt/extconf.rb"]
|
43
43
|
spec.files = FILES.to_a
|
44
44
|
spec.test_files = Dir.glob("test/tc_*.rb")
|
45
|
-
|
46
|
-
spec.required_ruby_version = '>= 1.8.
|
45
|
+
|
46
|
+
spec.required_ruby_version = '>= 1.8.6'
|
47
47
|
spec.date = DateTime.now
|
48
48
|
spec.rubyforge_project = 'libxslt-ruby'
|
49
|
-
end
|
49
|
+
end
|