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