class LibXSLT::XSLT::Stylesheet
The XSLT::Stylesheet represents a XSL stylesheet that can be used to transform an XML document. For usage information refer to XSLT::Stylesheet#apply
Constants
- PARSE_OPTIONS
options to be used for parsing stylesheets
Public Class Methods
create a xslt stylesheet from a file specified by its filename
# File lib/libxslt/stylesheet.rb 14 def self.file(filename) 15 doc = LibXML::XML::Parser.file(filename, :options => PARSE_OPTIONS).parse 16 return new(doc) 17 end
create a xslt stylesheet from an io object
# File lib/libxslt/stylesheet.rb 20 def self.io(io_object) 21 doc = LibXML::XML::Parser.io(io_object, :options => PARSE_OPTIONS).parse 22 return new(doc) 23 end
Creates a new XSLT stylesheet based on the specified document. For memory management reasons, a copy of the specified document will be made, so its best to create a single copy of a stylesheet and use it multiple times.
stylesheet_doc = XML::Document.file('stylesheet_file') stylesheet = XSLT::Stylesheet.new(stylesheet_doc)
static VALUE
ruby_xslt_stylesheet_initialize(VALUE self, VALUE document) {
xmlDocPtr xdoc;
xmlDocPtr xcopy;
xsltStylesheetPtr xstylesheet;
if (!rb_obj_is_kind_of(document, cXMLDocument))
rb_raise(rb_eTypeError, "Must pass in an XML::Document instance.");
/* NOTE!! Since the stylesheet own the specified document, the easiest
* thing to do from a memory standpoint is too copy it and not expose
* the copy to Ruby. The other solution is expose a memory management
* API on the document object for taking ownership of the document
* and specifying when it has been freed. Then the document class
* has to be updated to always check and see if the document is
* still valid. That's all doable, but seems like a pain, so
* just copy the document for now. */
Data_Get_Struct(document, xmlDoc, xdoc);
xcopy = xmlCopyDoc(xdoc, 1);
xstylesheet = xsltParseStylesheetDoc(xcopy);
xstylesheet->_private = (void *)self;
DATA_PTR(self) = xstylesheet;
/* Save a reference to the document as an attribute accessable to ruby */
return self;
}
create a xslt stylesheet from a string
# File lib/libxslt/stylesheet.rb 8 def self.string(xml) 9 doc = LibXML::XML::Parser.string(xml, :options => PARSE_OPTIONS).parse 10 return new(doc) 11 end
Public Instance Methods
Apply this stylesheet transformation to the provided document. This method may be invoked multiple times.
Params:
-
document - An instance of an XML::Document
-
params - An optional hash table that specifies the values for xsl:param values embedded in the stylesheet.
Example:
stylesheet_doc = XML::Document.file('stylesheet_file') stylesheet = XSLT::Stylesheet.new(stylesheet_doc) xml_doc = XML::Document.file('xml_file') result = stylesheet.apply(xml_doc) result = stylesheet.apply(xml_doc, {:foo => 'bar'})
static VALUE
ruby_xslt_stylesheet_apply(int argc, VALUE *argv, VALUE self) {
xmlDocPtr xdoc;
xsltStylesheetPtr xstylesheet;
xmlDocPtr result;
VALUE document;
VALUE params;
int i;
char** pParams;
if (argc > 2 || argc < 1)
rb_raise(rb_eArgError, "wrong number of arguments (need 1 or 2)");
document = argv[0];
if (!rb_obj_is_kind_of(document, cXMLDocument))
rb_raise(rb_eTypeError, "Must pass in an XML::Document instance.");
/* Make sure params is a flat array */
params = (argc == 2 ? argv[1]: Qnil);
params = rb_Array(params);
rb_funcall(params, rb_intern("flatten!"), 0);
pParams = ruby_xslt_coerce_params(params);
Data_Get_Struct(document, xmlDoc, xdoc);
Data_Get_Struct(self, xsltStylesheet, xstylesheet);
result = xsltApplyStylesheet(xstylesheet, xdoc, (const char**)pParams);
if (!result)
rb_raise(eXSLTError, "Transformation failed");
/* Free allocated array of *chars. Note we don't have to
free the last array item since its set to NULL. */
for (i=0; i<RARRAY_LEN(params); i++) {
ruby_xfree(pParams[i]);
}
ruby_xfree(pParams);
return rxml_document_wrap(result);
}
Output an xml document, usually the result of an xslt transformation, and return the result as a string. Output will be done according to the output specification in the xslt stylesheet. Note that this includes the encoding of the string.
VALUE
ruby_xslt_stylesheet_output(VALUE self, VALUE document) {
// FIXME: set string encoding in ruby 1.9?
xmlDocPtr xdoc;
xsltStylesheetPtr xstylesheet;
xmlChar *result = NULL;
int len = 0, bytes = 0;
VALUE rresult;
if (!rb_obj_is_kind_of(document, cXMLDocument))
rb_raise(rb_eTypeError, "Must pass in an XML::Document instance.");
Data_Get_Struct(document, xmlDoc, xdoc);
Data_Get_Struct(self, xsltStylesheet, xstylesheet);
bytes = xsltSaveResultToString(&result, &len,
xdoc, xstylesheet);
if ( bytes == -1 ) {
rb_raise(rb_eRuntimeError, "error dumping document");
}
rresult=rb_str_new((const char*)result,len);
xmlFree(result);
return rresult;
}
transform a xml to a string
# File lib/libxslt/stylesheet.rb 26 def transform(doc) 27 return output(apply(doc)) 28 end