Re: [xslt] document re-use between contexts

jason haslup said:
> Hello,
> We're using libxslt to create a large number of transaction files on
> individual input files.  Up until recently everything's been great,
> but I tried adding an extra document to the transform that contains
> static schema information that's used for lookups in the .xsl and am
> having some issues.  I add that already-parsed xmlDocPtr to my
> transform context using xsltNewDocument().

Hmmm.. I don't think I really understand why you want to do this,
but that's probably just me.. It should be your right and privilege,
so just ignore my confusion.

> The problem comes around when, after we've done an
> xsltApplyStylesheetUser(), we dutifully call
> xsltFreeTransformContext() on our context.  This function runs
> through
> all of its documents and not only free()'s its xsltDocument, but
> also
> the xmlDocPtr that was given to it using xsltNewDocument().  I'd
> rather it skip the xmlFreeDoc() since I want to re-use it without
> having to re-parse or copy the doc for each new context.
> I'm not sure if we're doing something non-standard, but assuming
> not,
> it seems to me that a new function or flag might be nice in order to
> keep ownership of the xmlDocPtr that's used in xsltNewDocument.
> Then,
> during xsltFreeDocuments(), this flag could be checked before
> calling
> xmlFreeDoc().

I have an even better idea here - why don't you use the existing
flag that already does exactly what you want :-)?

OK, please pardon my somewhat warped sense of humour - I really must
admit that it is *not* at all obvious that this flag exists, and the
documentation is *certainly* less than helpful.  On the other hand,
before your post I personally knew nothing about it - I just took a
look at the source for xmlNewDocument, together with the (few)
places within the library where it is called.

The xsltDocument structure contains a (flag) field named "main",
which I guess was chosen to show that it is the "main" document
being processed by the stylesheet.  The *only* use for this flag is
to indicate that, when the transform context is being freed, this
document should not be freed.  So, after your call to xsltDocument,
set doc->main = 1, and you should get the behaviour you desire.

I'll enhance the documentation on this (as you may know, the "docs"
are really just extractions from the source code) to assure that, in
the future, it will be more apparent.

> I would be more than willing to contribute these changes... we'd
> rather have them in the main libxslt distribution than support our
> own
> patch.  But before creating a patch, any feedback would be
> appreciated.  I propose:

If you feel that this feedback was useful to you, one excellent way
to indicate your appreciation would be to take a look at one of the
outstanding Bugzilla entries in either libxml2 or libxslt and
propose a patch to fix it :-)

> struct _xsltDocument {
>     struct _xsltDocument *next; /* documents are kept in a chained
>     list */
>     int main;                   /* is this the main document */
>     xmlDocPtr doc;                 /* the parsed document */
>     int staticDoc;      /* if set, don't xmlDocFree the doc */
>     void *keys;               /* key tables storage */
> };
> xsltNewStaticDocument(xsltTransformContextPtr ctxt, xmlDocPtr doc)
> {
>    call xsltNewDocument
>    set staticDoc = 1
> }
> There's already a memset(0,...) in xsltNewDocument so the default
> value of staticDoc will maintain current behavior.
> And finally, during the free, in addition to checking doc->main,
> check
> doc->staticDoc before calling xmlFreeDoc().
> Thanks for any comments,
> jason haslup

Thanks for your interest, and hope this will solve the problem for you.


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]