Hi all.
I had a problem with XML::LibXSLT: if I set the file input callbacks, they were called at the time of stylesheet parsing (to get to resources requested by xsl:include and xsl:import, for example), but not at runtime (to get the resources requested by document(), for example).
So I dig into the sources, and came up with the attached patch.
What it does:
- first of all, it calls 'xmlRegisterInputCallbacks' right before calling 'xsltApplyStylesheet', and calls 'xmlCleanupInputCallbacks' right after. This assures that the C callback wrappers (LibXSLT_input_match etc.) get called during the execution of the stylesheet
- it wraps XML::LibXSLT::Stylesheet::transform (and transform_file) in a Perl function that ('local'ly) sets XML::LibXSLT::match_cb etc so that the C callback wrappers know what to call
- it manages per-instance callbacks using inside-out objects, that is:
- XML::LibXSLT::parse_stylesheet creates an entry in %XML::LibXSLT::Stylesheet::owner for each stylesheet pointing to the XML::LibXSLT instance that created it
- the Perl 'transform' and 'transform_file' functions use that hash to retrieve the correct callbacks
Works for me, hope this fixes once and for all the problems we were having with the callbacks
-- Dakkar - <Mobilis in mobile> GPG public key fingerprint = A071 E618 DD2C 5901 9574 6FE2 40EA 9883 7519 3F88 key id = 0x75193F88
Index: LibXSLT.pm =================================================================== RCS file: /home/cvs/XML-LibXSLT/LibXSLT.pm,v retrieving revision 1.49 diff -u -r1.49 LibXSLT.pm --- LibXSLT.pm 2004/04/21 17:10:47 1.49 +++ LibXSLT.pm 2004/05/22 08:18:30 @@ -136,7 +136,9 @@ local $XML::LibXSLT::close_cb = $self->{XML_LIBXSLT_CLOSE}; #warn "localised callbacks: $XML::LibXML::match_cb $XML::LibXML::open_cb $XML::LibXML::read_cb $XML::LibXML::close_cb"; - $self->_parse_stylesheet(@_); + my $ret=$self->_parse_stylesheet(@_); + $XML::LibXSLT::Stylesheet::owner{$ret}=$self; + return $ret; } sub parse_stylesheet_file { @@ -151,13 +153,51 @@ local $XML::LibXSLT::close_cb = $self->{XML_LIBXSLT_CLOSE}; #warn "localised callbacks: $XML::LibXML::match_cb $XML::LibXML::open_cb $XML::LibXML::read_cb $XML::LibXML::close_cb"; - $self->_parse_stylesheet_file(@_); + my $ret=$self->_parse_stylesheet_file(@_); + $XML::LibXSLT::Stylesheet::owner{$ret}=$self; + return $ret; } sub register_xslt_module { my $self = shift; my $module = shift; # Not implemented +} + +package XML::LibXSLT::Stylesheet; + +our %owner; + +sub transform { + my $self = shift; + my $owner=$XML::LibXSLT::Stylesheet::owner{$self}; + if (!ref($owner) || !$owner->{XML_LIBXSLT_MATCH}) { + #warn "callbacks: $XML::LibXML::match_cb $XML::LibXML::open_cb $XML::LibXML::read_cb $XML::LibXML::close_cb"; + return $self->_transform(@_); + } + local $XML::LibXSLT::match_cb = $owner->{XML_LIBXSLT_MATCH}; + local $XML::LibXSLT::open_cb = $owner->{XML_LIBXSLT_OPEN}; + local $XML::LibXSLT::read_cb = $owner->{XML_LIBXSLT_READ}; + local $XML::LibXSLT::close_cb = $owner->{XML_LIBXSLT_CLOSE}; + + #warn "localised callbacks: $XML::LibXML::match_cb $XML::LibXML::open_cb $XML::LibXML::read_cb $XML::LibXML::close_cb"; + $self->_transform(@_); +} + +sub transform_file { + my $self = shift; + my $owner=$XML::LibXSLT::Stylesheet::owner{$self}; + if (!ref($owner) || !$owner->{XML_LIBXSLT_MATCH}) { + #warn "callbacks: $XML::LibXML::match_cb $XML::LibXML::open_cb $XML::LibXML::read_cb $XML::LibXML::close_cb"; + return $self->_transform_file(@_); + } + local $XML::LibXSLT::match_cb = $owner->{XML_LIBXSLT_MATCH}; + local $XML::LibXSLT::open_cb = $owner->{XML_LIBXSLT_OPEN}; + local $XML::LibXSLT::read_cb = $owner->{XML_LIBXSLT_READ}; + local $XML::LibXSLT::close_cb = $owner->{XML_LIBXSLT_CLOSE}; + + #warn "localised callbacks: $XML::LibXML::match_cb $XML::LibXML::open_cb $XML::LibXML::read_cb $XML::LibXML::close_cb"; + $self->_transform_file(@_); } 1; Index: LibXSLT.xs =================================================================== RCS file: /home/cvs/XML-LibXSLT/LibXSLT.xs,v retrieving revision 1.60 diff -u -r1.60 LibXSLT.xs --- LibXSLT.xs 2004/04/21 19:37:03 1.60 +++ LibXSLT.xs 2004/05/22 08:18:31 @@ -693,7 +693,12 @@ else { xsltSetGenericDebugFunc(NULL, NULL); } + xmlRegisterInputCallbacks((xmlInputMatchCallback) LibXSLT_input_match, + (xmlInputOpenCallback) LibXSLT_input_open, + (xmlInputReadCallback) LibXSLT_input_read, + (xmlInputCloseCallback) LibXSLT_input_close); RETVAL = xsltParseStylesheetDoc(doc_copy); + xmlCleanupInputCallbacks(); if (RETVAL == NULL) { XSRETURN_UNDEF; } @@ -714,7 +719,12 @@ else { xsltSetGenericDebugFunc(NULL, NULL); } + xmlRegisterInputCallbacks((xmlInputMatchCallback) LibXSLT_input_match, + (xmlInputOpenCallback) LibXSLT_input_open, + (xmlInputReadCallback) LibXSLT_input_read, + (xmlInputCloseCallback) LibXSLT_input_close); RETVAL = xsltParseStylesheetFile(filename); + xmlCleanupInputCallbacks(); if (RETVAL == NULL) { XSRETURN_UNDEF; } @@ -726,7 +736,7 @@ PROTOTYPES: DISABLE SV * -transform(self, sv_doc, ...) +_transform(self, sv_doc, ...) xsltStylesheetPtr self SV * sv_doc PREINIT: @@ -766,7 +776,12 @@ else { xsltSetGenericDebugFunc(NULL, NULL); } + xmlRegisterInputCallbacks((xmlInputMatchCallback) LibXSLT_input_match, + (xmlInputOpenCallback) LibXSLT_input_open, + (xmlInputReadCallback) LibXSLT_input_read, + (xmlInputCloseCallback) LibXSLT_input_close); real_dom = xsltApplyStylesheet(self, doc, xslt_params); + xmlCleanupInputCallbacks(); if (real_dom == NULL) { if (SvTRUE(ERRSV)) { croak("Exception occurred while applying stylesheet: %s", SvPV(ERRSV, len)); @@ -785,7 +800,7 @@ RETVAL SV * -transform_file(self, filename, ...) +_transform_file(self, filename, ...) xsltStylesheetPtr self char * filename PREINIT: @@ -816,7 +831,12 @@ else { xsltSetGenericDebugFunc(NULL, NULL); } + xmlRegisterInputCallbacks((xmlInputMatchCallback) LibXSLT_input_match, + (xmlInputOpenCallback) LibXSLT_input_open, + (xmlInputReadCallback) LibXSLT_input_read, + (xmlInputCloseCallback) LibXSLT_input_close); real_dom = xsltApplyStylesheet(self, xmlParseFile(filename), xslt_params); + xmlCleanupInputCallbacks(); if (real_dom == NULL) { if (SvTRUE(ERRSV)) { croak("Error applying stylesheet: %s", SvPV(ERRSV, len));
signature.asc
Description: OpenPGP digital signature