Created
October 7, 2014 19:49
-
-
Save sshao/8911889131aad079d283 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* call-seq: | |
| * stylesheet.apply(document, {params}) -> XML::Document | |
| * | |
| * 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) { | |
| 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); | |
| } | |
| /* call-seq: | |
| * sheet.debug(to = $stdout) => (true|false) | |
| * | |
| * Output a debug dump of this stylesheet to the specified output | |
| * stream (an instance of IO, defaults to $stdout). Requires | |
| * libxml/libxslt be compiled with debugging enabled. If this | |
| * is not the case, a warning is triggered and the method returns | |
| * false. | |
| */ | |
| /*VALUE | |
| ruby_xslt_stylesheet_debug(int argc, VALUE *argv, VALUE self) { | |
| #ifdef LIBXML_DEBUG_ENABLED | |
| OpenFile *fptr; | |
| VALUE io; | |
| FILE *out; | |
| rxml_document_t *parsed; | |
| ruby_xslt_stylesheet *xss; | |
| Data_Get_Struct(self, ruby_xslt_stylesheet, xss); | |
| if (NIL_P(xss->parsed)) | |
| rb_raise(eXMLXSLTStylesheetRequireParsedDoc, "must have a parsed XML result"); | |
| switch (argc) { | |
| case 0: | |
| io = rb_stdout; | |
| break; | |
| case 1: | |
| io = argv[0]; | |
| if (rb_obj_is_kind_of(io, rb_cIO) == Qfalse) | |
| rb_raise(rb_eTypeError, "need an IO object"); | |
| break; | |
| default: | |
| rb_raise(rb_eArgError, "wrong number of arguments (0 or 1)"); | |
| } | |
| Data_Get_Struct(xss->parsed, rxml_document_t, parsed); | |
| if (parsed->doc == NULL) | |
| return(Qnil); | |
| GetOpenFile(io, fptr); | |
| rb_io_check_writable(fptr); | |
| out = GetWriteFile(fptr); | |
| xmlDebugDumpDocument(out, parsed->doc); | |
| return(Qtrue); | |
| #else | |
| rb_warn("libxml/libxslt was compiled without debugging support. Please recompile libxml/libxslt and their Ruby modules"); | |
| return(Qfalse); | |
| #endif | |
| } | |
| */ | |
| /* TODO should this automatically apply the sheet if not already, | |
| given that we're unlikely to do much else with it? */ | |
| /* call-seq: | |
| * sheet.print(to = $stdout) => number_of_bytes | |
| * | |
| * Output the result of the transform to the specified output | |
| * stream (an IO instance, defaults to $stdout). You *must* call | |
| * +apply+ before this method or an exception will be raised. | |
| */ | |
| /*VALUE | |
| ruby_xslt_stylesheet_print(int argc, VALUE *argv, VALUE self) { | |
| OpenFile *fptr; | |
| VALUE io; | |
| FILE *out; | |
| rxml_document_t *parsed; | |
| ruby_xslt_stylesheet *xss; | |
| int bytes; | |
| Data_Get_Struct(self, ruby_xslt_stylesheet, xss); | |
| if (NIL_P(xss->parsed)) | |
| rb_raise(eXMLXSLTStylesheetRequireParsedDoc, "must have a parsed XML result"); | |
| switch (argc) { | |
| case 0: | |
| io = rb_stdout; | |
| break; | |
| case 1: | |
| io = argv[0]; | |
| if (rb_obj_is_kind_of(io, rb_cIO) == Qfalse) | |
| rb_raise(rb_eTypeError, "need an IO object"); | |
| break; | |
| default: | |
| rb_raise(rb_eArgError, "wrong number of arguments (0 or 1)"); | |
| } | |
| Data_Get_Struct(xss->parsed, rxml_document_t, parsed); | |
| if (parsed->doc == NULL) | |
| return(Qnil); | |
| GetOpenFile(io, fptr); | |
| rb_io_check_writable(fptr); | |
| out = GetWriteFile(fptr); | |
| bytes = xsltSaveResultToFile(out, parsed->doc, xss->xsp); | |
| return(INT2NUM(bytes)); | |
| }*/ | |
| /* call-seq: | |
| * stylesheet.output(doc) => string | |
| * | |
| * 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; | |
| } | |
| #ifdef RDOC_NEVER_DEFINED | |
| cLibXSLT = rb_define_module("LibXSLT"); | |
| cXSLT = rb_define_module_under(cLibXSLT, "XSLT"); | |
| #endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment