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));

Attachment: signature.asc
Description: OpenPGP digital signature



Reply via email to