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

file(filename) click to toggle source

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
io(io_object) click to toggle source

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
XSLT::Stylesheet.new(document) → XSLT::Stylesheet click to toggle source

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;
}
string(xml) click to toggle source

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(document, {params}) → XML::Document click to toggle source

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(doc) → string click to toggle source

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(doc) click to toggle source

transform a xml to a string

   # File lib/libxslt/stylesheet.rb
26 def transform(doc)
27   return output(apply(doc))
28 end