class XML::XSLT

Constants

DEFAULT_URL
DEFAULT_VENDOR
DEFAULT_VERSION
ENGINE_VERSION
LIBXML_VERSION
LIBXSLT_VERSION
MAX_DEPTH
MAX_SORT
NAMESPACE_LIBXSLT
NAMESPACE_NORM_SAXON
NAMESPACE_SAXON
NAMESPACE_XALAN
NAMESPACE_XT
RUBY_XSLT_VERSION
XSLT_NAMESPACE

Public Class Methods

new() click to toggle source

oXSLT = ::new

Create a new XML::XSLT object

VALUE ruby_xslt_new( VALUE class ) {
  RbTxslt *pRbTxslt;

  pRbTxslt = (RbTxslt *)malloc(sizeof(RbTxslt));
  if( pRbTxslt == NULL )
    rb_raise(rb_eNoMemError, "No memory left for XSLT struct");

  pRbTxslt->iXmlType        = RUBY_XSLT_XMLSRC_TYPE_NULL;
  pRbTxslt->xXmlData        = Qnil;
  pRbTxslt->oXmlObject      = Qnil;
  pRbTxslt->xXmlString      = Qnil;
  pRbTxslt->tXMLDocument    = NULL;
  
  pRbTxslt->iXslType        = RUBY_XSLT_XSLSRC_TYPE_NULL;
  pRbTxslt->xXslData        = Qnil;
  pRbTxslt->oXslObject      = Qnil;
  pRbTxslt->xXslString      = Qnil;
  pRbTxslt->tParsedXslt     = NULL;
  
  pRbTxslt->iXmlResultType  = RUBY_XSLT_XMLSRC_TYPE_NULL;
  pRbTxslt->xXmlResultCache = Qnil;
  
  pRbTxslt->pxParams        = Qnil;
  pRbTxslt->iNbParams       = 0;
  
  xmlInitMemory();
  xmlSubstituteEntitiesDefault( 1 );
  xmlLoadExtDtdDefaultValue = 1;
  
  return( Data_Wrap_Struct( class, ruby_xslt_mark, ruby_xslt_free, pRbTxslt ) );
}
registerErrorHandler(&block) click to toggle source

registers a block to be called when libxml2 or libxslt encounter an error eg:

XML::XSLT.registerErrorHandler do |error_str|
  $stderr.puts error_str
end
# File lib/xml/xslt.rb, line 67
def self.registerErrorHandler(&block)
  @@error_handler = block
end
Also aliased as: register_error_handler
registerExtFunc(namespace, name, &block) click to toggle source

sets up a block for callback when the XPath function namespace:name( … ) is encountered in a stylesheet.

XML::XSLT.registerExtFunc(namespace_uri, name) do |*args|
  puts args.inspect
end

XPath arguments are converted to Ruby objects accordingly:

number (eg. 1)

Float

boolean (eg. false())

TrueClass/FalseClass

nodeset (eg. /entry/*)

Array of REXML::Elements

variable (eg. $var)

UNIMPLEMENTED

It works the same in the other direction, eg. if the block returns an array of REXML::Elements the value of the function will be a nodeset.

Note: currently, passing a nodeset to Ruby or REXML::Elements to libxslt serializes the nodes and then parses them. Doing this with large sets is a bad idea. In the future they'll be passed back and forth using Ruby's libxml2 bindings.

# File lib/xml/xslt.rb, line 47
def self.registerExtFunc(namespace, name, &block)
  @@extFunctions[namespace] ||= {}
  @@extFunctions[namespace][name] = block
  XML::XSLT.registerFunction(namespace, name)
end
Also aliased as: register_ext_func
registerFunction(p1, p2) click to toggle source

internal use only.

VALUE ruby_xslt_reg_function( VALUE class, VALUE namespace, VALUE name ) {
   xsltRegisterExtModuleFunction( BAD_CAST StringValuePtr(name), BAD_CAST StringValuePtr(namespace), xmlXPathFuncCallback );

   return Qnil;
 }

/** 
 * string = oXSLT.xsl_to_s( ) 
 */
VALUE ruby_xslt_to_s( VALUE self ) {
  VALUE vStrOut;
  RbTxslt *pRbTxslt;
  xsltStylesheetPtr vXSLTSheet = NULL;
  const char *xKlassName = rb_class2name( CLASS_OF( self ) );

  Data_Get_Struct( self, RbTxslt, pRbTxslt );

  //vXSLTSheet = xsltParseStylesheetDoc( xmlParseMemory( StringValuePtr( pRbTxslt->xXslData ), strlen( StringValuePtr( pRbTxslt->xXslData ) ) ) );
  vXSLTSheet = pRbTxslt->tParsedXslt;
  if (vXSLTSheet == NULL) return Qnil;

  vStrOut = rb_str_new( 0, strlen(xKlassName)+1024 );
  (void) sprintf( RSTRING_PTR(vStrOut),
         "#<%s: parent=%p,next=%p,imports=%p,docList=%p,"
         "doc=%p,stripSpaces=%p,stripAll=%d,cdataSection=%p,"
         "variables=%p,templates=%p,templatesHash=%p,"
         "rootMatch=%p,keyMatch=%p,elemMatch=%p,"
         "attrMatch=%p,parentMatch=%p,textMatch=%p,"
         "piMatch=%p,commentMatch=%p,nsAliases=%p,"
         "attributeSets=%p,nsHash=%p,nsDefs=%p,keys=%p,"
         "method=%s,methodURI=%s,version=%s,encoding=%s,"
         "omitXmlDeclaration=%d,decimalFormat=%p,standalone=%d,"
         "doctypePublic=%s,doctypeSystem=%s,indent=%d,"
         "mediaType=%s,preComps=%p,warnings=%d,errors=%d,"
         "exclPrefix=%s,exclPrefixTab=%p,exclPrefixNr=%d,"
         "exclPrefixMax=%d>",
         xKlassName,
         vXSLTSheet->parent, vXSLTSheet->next, vXSLTSheet->imports, vXSLTSheet->docList,
         vXSLTSheet->doc, vXSLTSheet->stripSpaces, vXSLTSheet->stripAll, vXSLTSheet->cdataSection,
         vXSLTSheet->variables, vXSLTSheet->templates, vXSLTSheet->templatesHash,
         vXSLTSheet->rootMatch, vXSLTSheet->keyMatch, vXSLTSheet->elemMatch,
         vXSLTSheet->attrMatch, vXSLTSheet->parentMatch, vXSLTSheet->textMatch,
         vXSLTSheet->piMatch, vXSLTSheet->commentMatch, vXSLTSheet->nsAliases,
         vXSLTSheet->attributeSets, vXSLTSheet->nsHash, vXSLTSheet->nsDefs, vXSLTSheet->keys,
         vXSLTSheet->method, vXSLTSheet->methodURI, vXSLTSheet->version, vXSLTSheet->encoding,
         vXSLTSheet->omitXmlDeclaration, vXSLTSheet->decimalFormat, vXSLTSheet->standalone,
         vXSLTSheet->doctypePublic, vXSLTSheet->doctypeSystem, vXSLTSheet->indent,
         vXSLTSheet->mediaType, vXSLTSheet->preComps, vXSLTSheet->warnings, vXSLTSheet->errors,
         vXSLTSheet->exclPrefix, vXSLTSheet->exclPrefixTab, vXSLTSheet->exclPrefixNr,
         vXSLTSheet->exclPrefixMax );

  vStrOut = strlen(RSTRING_PTR(vStrOut));
  if( OBJ_TAINTED(self) ) OBJ_TAINT(vStrOut);

  // xsltFreeStylesheet(vXSLTSheet);

  return( vStrOut );
}
register_error_handler(&block)
register_ext_func(namespace, name, &block)
Alias for: registerExtFunc

Public Instance Methods

mediaType() click to toggle source

mediaTypeString = #mediaType( )

Return the XSL output's media type

VALUE ruby_xslt_media_type( VALUE self ) {
  RbTxslt *pRbTxslt;
  xsltStylesheetPtr vXSLTSheet = NULL;
  
  Data_Get_Struct( self, RbTxslt, pRbTxslt );

  vXSLTSheet = pRbTxslt->tParsedXslt;
  
  if ( (vXSLTSheet == NULL) || (vXSLTSheet->mediaType == NULL) ) {
    return Qnil;
  } else {
    return rb_str_new2( (char *)(vXSLTSheet->mediaType) );
  }
}
Also aliased as: media_type
media_type()
Alias for: mediaType
parameters=(p1) click to toggle source

oXSLT.parameters={ “key” => “value”, “key” => “value”, … }

VALUE ruby_xslt_parameters_set( VALUE self, VALUE parameters ) {
  RbTxslt *pRbTxslt;
  Check_Type( parameters, T_HASH );
    
  Data_Get_Struct( self, RbTxslt, pRbTxslt );

  if( !NIL_P(parameters) ){
    pRbTxslt->pxParams = rb_ary_new( );
    // each_pair and process_pair defined ind parameters.c
    (void)rb_iterate( each_pair, parameters, process_pair, pRbTxslt->pxParams );
    pRbTxslt->iNbParams = FIX2INT( rb_funcall( parameters, rb_intern("size"), 0, 0 ) ) * 2 + 2;
    pRbTxslt->iXmlResultType = RUBY_XSLT_XMLSRC_TYPE_NULL;
  }
    
  return( Qnil );
}
save(p1) click to toggle source

#save( “result.xml” )

Save the stylesheet transformation to file

VALUE ruby_xslt_save( VALUE self, VALUE xOutFilename ) {
  char *xOut;
  VALUE rOut;
  FILE *fOutFile;
  
  rOut = ruby_xslt_serve( self );
  
  if( rOut != Qnil ) {
    xOut = StringValuePtr( rOut );
  
    fOutFile = fopen( StringValuePtr( xOutFilename ), "w" );
    if( fOutFile == NULL ) {
      free( xOut );
      rb_raise( rb_eRuntimeError, "Can't create file %s\n", StringValuePtr( xOutFilename ) );
      rOut = Qnil;
    } else {
      fwrite( xOut, 1, strlen( xOut ), fOutFile );
      fclose( fOutFile );
    }
  }

  return( rOut );
}
serve() click to toggle source

output_string = #serve( )

Return the stylesheet transformation

VALUE ruby_xslt_serve( VALUE self ) {
  RbTxslt *pRbTxslt;
  char *xOut;
  char **pxParams = NULL;
  
  Data_Get_Struct( self, RbTxslt, pRbTxslt );

  if( pRbTxslt->iXmlResultType == RUBY_XSLT_XMLSRC_TYPE_NULL ) {

    if( pRbTxslt->pxParams != Qnil ){
      int iCpt;
    
      pxParams = (char **)ALLOCA_N( void *, pRbTxslt->iNbParams );
      MEMZERO( pxParams, void *, pRbTxslt->iNbParams );

      for( iCpt = 0; iCpt <= pRbTxslt->iNbParams - 3; iCpt++ ) {
                                VALUE tmp = rb_ary_entry( pRbTxslt->pxParams, iCpt );
        pxParams[iCpt] = StringValuePtr( tmp );
      }
    }
    
    if( pRbTxslt->iXslType != RUBY_XSLT_XSLSRC_TYPE_NULL &&
        pRbTxslt->iXmlType != RUBY_XSLT_XMLSRC_TYPE_NULL ) {
      xOut = parse( pRbTxslt->tParsedXslt, pRbTxslt->tXMLDocument, pxParams );
      if( xOut == NULL ) {
        pRbTxslt->xXmlResultCache = Qnil;
        pRbTxslt->iXmlResultType = RUBY_XSLT_XMLSRC_TYPE_NULL;
      } else {
        pRbTxslt->xXmlResultCache = rb_str_new2( xOut );
        pRbTxslt->iXmlResultType = RUBY_XSLT_XMLSRC_TYPE_STR;
                                free( xOut );
      }
    } else {
      pRbTxslt->xXmlResultCache = Qnil;
      pRbTxslt->iXmlResultType = RUBY_XSLT_XMLSRC_TYPE_NULL;
    }
  }

  return( pRbTxslt->xXmlResultCache );
}
xml() click to toggle source

string = #xml

Return XML, set by #xml=, as string

VALUE ruby_xslt_xml_2str_get( VALUE self ) {
  RbTxslt *pRbTxslt;
  Data_Get_Struct( self, RbTxslt, pRbTxslt );

  return( pRbTxslt->xXmlString );
}
xml=(p1) click to toggle source

#xml=<data|REXML::Document|XML::Smart|file>

Set XML data.

Parameter can be type String, REXML::Document, XML::Smart::Dom or Filename

Examples :

# Parameter as String
oXSLT.xml = <<XML
<?xml version="1.0" encoding="UTF-8"?> 
<test>This is a test string</test>
XML

# Parameter as REXML::Document
require 'rexml/document'
oXSLT.xml = REXML::Document.new File.open( "test.xml" )

# Parameter as XML::Smart::Dom
require 'xml/smart'
oXSLT.xml = XML::Smart.open( "test.xml" )

# Parameter as Filename
oXSLT.xml = "test.xml"
VALUE ruby_xslt_xml_obj_set( VALUE self, VALUE xml_doc_obj ) {
  RbTxslt *pRbTxslt;
  Data_Get_Struct( self, RbTxslt, pRbTxslt );

  pRbTxslt->oXmlObject = xml_doc_obj;
  pRbTxslt->xXmlString = object_to_string( xml_doc_obj );
  if( pRbTxslt->xXmlString == Qnil ) {
    rb_raise( eXSLTError, "Can't get XML data" );
  }
  pRbTxslt->iXmlType   = RUBY_XSLT_XMLSRC_TYPE_STR;
  pRbTxslt->xXmlData   = pRbTxslt->xXmlString;
  
  pRbTxslt->iXmlResultType = RUBY_XSLT_XMLSRC_TYPE_NULL;

        if( pRbTxslt->tXMLDocument != NULL ) {
                xmlFreeDoc(pRbTxslt->tXMLDocument);
        }
        
  pRbTxslt->tXMLDocument = parse_xml( StringValuePtr( pRbTxslt->xXmlData ), pRbTxslt->iXmlType );
  if( pRbTxslt->tXMLDocument == NULL ) {
    rb_raise( eXSLTParsingError, "XML parsing error" );
  }
  
  pRbTxslt->iXmlType   = RUBY_XSLT_XMLSRC_TYPE_PARSED;
  
  return( Qnil );
}
xmlfile=(p1) click to toggle source

#xmlfile=<file> is deprecated. Please use #xml=<file>

VALUE ruby_xslt_xml_obj_set_d( VALUE self, VALUE xml_doc_obj ) {
  rb_warn( "XML::XSLT#xmlfile=<file> is deprecated. Please use XML::XSLT#xml=<file> !" );
  return( ruby_xslt_xml_obj_set( self, xml_doc_obj ) );
}
xmlobject() click to toggle source

object = #xmlobject

Return the XML object set by #xml=

VALUE ruby_xslt_xml_2obj_get( VALUE self ) {
  RbTxslt *pRbTxslt;
  Data_Get_Struct( self, RbTxslt, pRbTxslt );

  return( pRbTxslt->oXmlObject );
}
xsl() click to toggle source

string = #xsl

Return XSL, set by #xsl=, as string

VALUE ruby_xslt_xsl_2str_get( VALUE self ) {
  RbTxslt *pRbTxslt;
  Data_Get_Struct( self, RbTxslt, pRbTxslt );

  return( pRbTxslt->xXslString );
}
xsl=(p1) click to toggle source

#xsl=<data|REXML::Document|XML::Smart|file>

Set XSL data.

Parameter can be type String, REXML::Document, XML::Smart::Dom or Filename

Examples :

# Parameter as String
oXSLT.xsl = <<XML
<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
 <xsl:template match="/">
   <xsl:apply-templates />
 </xsl:template>
</xsl:stylesheet>
XML

# Parameter as REXML::Document
require 'rexml/document'
oXSLT.xsl = REXML::Document.new File.open( "test.xsl" )

# Parameter as XML::Smart::Dom
require 'xml/smart'
oXSLT.xsl = XML::Smart.open( "test.xsl" )

# Parameter as Filename
oXSLT.xsl = "test.xsl"
VALUE ruby_xslt_xsl_obj_set( VALUE self, VALUE xsl_doc_obj ) {
  RbTxslt *pRbTxslt;
  Data_Get_Struct( self, RbTxslt, pRbTxslt );

  pRbTxslt->oXslObject = xsl_doc_obj;
  pRbTxslt->xXslString = object_to_string( xsl_doc_obj );
  if( pRbTxslt->xXslString == Qnil ) {
    rb_raise( eXSLTError, "Can't get XSL data" );
  }
  
  if( objectIsFile( xsl_doc_obj ) ) {
    pRbTxslt->iXslType = RUBY_XSLT_XSLSRC_TYPE_FILE;
    pRbTxslt->xXslData = pRbTxslt->oXslObject;
  } else {
    pRbTxslt->iXslType = RUBY_XSLT_XSLSRC_TYPE_STR;
    pRbTxslt->xXslData = pRbTxslt->xXslString;
  }
  
  pRbTxslt->iXmlResultType = RUBY_XSLT_XMLSRC_TYPE_NULL;
  
        if( pRbTxslt->tParsedXslt != NULL ) {
          xsltFreeStylesheet(pRbTxslt->tParsedXslt);
        }
        
  pRbTxslt->tParsedXslt = parse_xsl( StringValuePtr( pRbTxslt->xXslData ), pRbTxslt->iXslType );
  if( pRbTxslt->tParsedXslt == NULL ) {
    rb_raise( eXSLTParsingError, "XSL Stylesheet parsing error" );
  }
  
  pRbTxslt->iXslType   = RUBY_XSLT_XSLSRC_TYPE_PARSED;

  return( Qnil );
}
xsl_to_s() click to toggle source

string = #xsl_to_s( )

VALUE ruby_xslt_to_s( VALUE self ) {
  VALUE vStrOut;
  RbTxslt *pRbTxslt;
  xsltStylesheetPtr vXSLTSheet = NULL;
  const char *xKlassName = rb_class2name( CLASS_OF( self ) );

  Data_Get_Struct( self, RbTxslt, pRbTxslt );

  //vXSLTSheet = xsltParseStylesheetDoc( xmlParseMemory( StringValuePtr( pRbTxslt->xXslData ), strlen( StringValuePtr( pRbTxslt->xXslData ) ) ) );
  vXSLTSheet = pRbTxslt->tParsedXslt;
  if (vXSLTSheet == NULL) return Qnil;

  vStrOut = rb_str_new( 0, strlen(xKlassName)+1024 );
  (void) sprintf( RSTRING_PTR(vStrOut),
         "#<%s: parent=%p,next=%p,imports=%p,docList=%p,"
         "doc=%p,stripSpaces=%p,stripAll=%d,cdataSection=%p,"
         "variables=%p,templates=%p,templatesHash=%p,"
         "rootMatch=%p,keyMatch=%p,elemMatch=%p,"
         "attrMatch=%p,parentMatch=%p,textMatch=%p,"
         "piMatch=%p,commentMatch=%p,nsAliases=%p,"
         "attributeSets=%p,nsHash=%p,nsDefs=%p,keys=%p,"
         "method=%s,methodURI=%s,version=%s,encoding=%s,"
         "omitXmlDeclaration=%d,decimalFormat=%p,standalone=%d,"
         "doctypePublic=%s,doctypeSystem=%s,indent=%d,"
         "mediaType=%s,preComps=%p,warnings=%d,errors=%d,"
         "exclPrefix=%s,exclPrefixTab=%p,exclPrefixNr=%d,"
         "exclPrefixMax=%d>",
         xKlassName,
         vXSLTSheet->parent, vXSLTSheet->next, vXSLTSheet->imports, vXSLTSheet->docList,
         vXSLTSheet->doc, vXSLTSheet->stripSpaces, vXSLTSheet->stripAll, vXSLTSheet->cdataSection,
         vXSLTSheet->variables, vXSLTSheet->templates, vXSLTSheet->templatesHash,
         vXSLTSheet->rootMatch, vXSLTSheet->keyMatch, vXSLTSheet->elemMatch,
         vXSLTSheet->attrMatch, vXSLTSheet->parentMatch, vXSLTSheet->textMatch,
         vXSLTSheet->piMatch, vXSLTSheet->commentMatch, vXSLTSheet->nsAliases,
         vXSLTSheet->attributeSets, vXSLTSheet->nsHash, vXSLTSheet->nsDefs, vXSLTSheet->keys,
         vXSLTSheet->method, vXSLTSheet->methodURI, vXSLTSheet->version, vXSLTSheet->encoding,
         vXSLTSheet->omitXmlDeclaration, vXSLTSheet->decimalFormat, vXSLTSheet->standalone,
         vXSLTSheet->doctypePublic, vXSLTSheet->doctypeSystem, vXSLTSheet->indent,
         vXSLTSheet->mediaType, vXSLTSheet->preComps, vXSLTSheet->warnings, vXSLTSheet->errors,
         vXSLTSheet->exclPrefix, vXSLTSheet->exclPrefixTab, vXSLTSheet->exclPrefixNr,
         vXSLTSheet->exclPrefixMax );

  vStrOut = strlen(RSTRING_PTR(vStrOut));
  if( OBJ_TAINTED(self) ) OBJ_TAINT(vStrOut);

  // xsltFreeStylesheet(vXSLTSheet);

  return( vStrOut );
}
xslfile=(p1) click to toggle source

#xslfile=<file> is deprecated. Please use #xsl=<file>

VALUE ruby_xslt_xsl_obj_set_d( VALUE self, VALUE xsl_doc_obj ) {
  rb_warning( "XML::XSLT#xslfile=<file> is deprecated. Please use XML::XSLT#xsl=<file> !" );
  return( ruby_xslt_xsl_obj_set( self, xsl_doc_obj ) );
}
xslobject() click to toggle source

object = #xslobject

Return the XSL object set by #xsl=

VALUE ruby_xslt_xsl_2obj_get( VALUE self ) {
  RbTxslt *pRbTxslt;
  Data_Get_Struct( self, RbTxslt, pRbTxslt );

  return( pRbTxslt->oXslObject );
}