Location: http://xmlsoft.org/xmlio.html
Libxml home page: http://xmlsoft.org/
Mailing-list archive: http://xmlsoft.org/messages/
Version: $Revision: 1.3 $
Table of Content:
The module xmlIO.h
provides the interfaces to the libxml I/O system. This consists of 4 main
parts:
xmlGetExternalEntityLoader()
and
xmlSetExternalEntityLoader()
. Check the
example.This affect the default I/O operations and allows to use specific I/O handlers for certain names.
The general mechanism used when loading http://rpmfind.net/xml.html for example in the HTML parser is the following:
xmlNewInputFromFile()
with
the parsing context and the URI string.The user defined callbacks are checked first to allow overriding of the default libxml I/O routines.
All the buffer manipulation handling is done using the
xmlBuffer
type define in tree.h
which is
a resizable memory buffer. The buffer allocation strategy can be selected to
be either best-fit or use an exponential doubling one (CPU vs. memory use
tradeoff). The values are XML_BUFFER_ALLOC_EXACT
and
XML_BUFFER_ALLOC_DOUBLEIT
, and can be set individually or on a
system wide basis using xmlBufferSetAllocationScheme()
. A number
of functions allows to manipulate buffers with names starting with the
xmlBuffer...
prefix.
An Input I/O handler is a simple structure
xmlParserInputBuffer
containing a context associated to the
resource (file descriptor, or pointer to a protocol handler), the read() and
close() callbacks to use and an xmlBuffer. And extra xmlBuffer and a charset
encoding handler are also present to support charset conversion when
needed.
An Output handler xmlOutputBuffer
is completely similar to an
Input one except the callbacks are write() and close().
The entity loader resolves requests for new entities and create inputs for the parser. Creating an input from a filename or an URI string is done through the xmlNewInputFromFile() routine. The default entity loader do not handle the PUBLIC identifier associated with an entity (if any). So it just calls xmlNewInputFromFile() with the SYSTEM identifier (which is mandatory in XML).
If you want to hook up a catalog mechanism then you simply need to override the default entity loader, here is an example:
#include <libxml/xmlIO.h> xmlExternalEntityLoader defaultLoader = NULL; xmlParserInputPtr xmlMyExternalEntityLoader(const char *URL, const char *ID, xmlParserCtxtPtr ctxt) { xmlParserInputPtr ret; const char *fileID = NULL; /* lookup for the fileID depending on ID */ ret = xmlNewInputFromFile(ctxt, fileID); if (ret != NULL) return(ret); if (defaultLoader != NULL) ret = defaultLoader(URL, ID, ctxt); return(ret); } int main(..) { ... /* * Install our own entity loader */ defaultLoader = xmlGetExternalEntityLoader(); xmlSetExternalEntityLoader(xmlMyExternalEntityLoader); ... }
This example come from a real use case, xmlDocDump() closes the FILE * passed by the application and this was a problem. The solution was to redefine a new output handler with the closing call deactivated:
xmlOutputBufferPtr xmlOutputBufferCreateOwn(FILE *file, xmlCharEncodingHandlerPtr encoder) { xmlOutputBufferPtr ret; if (xmlOutputCallbackInitialized == 0) xmlRegisterDefaultOutputCallbacks(); if (file == NULL) return(NULL); ret = xmlAllocOutputBuffer(encoder); if (ret != NULL) { ret->context = file; ret->writecallback = xmlFileWrite; ret->closecallback = NULL; /* No close callback */ } return(ret);
}
FILE *f; xmlOutputBufferPtr output; xmlDocPtr doc; int res; f = ... doc = .... output = xmlOutputBufferCreateOwn(f, NULL); res = xmlSaveFileTo(output, doc, NULL);
$Id: xmlio.html,v 1.3 2000/08/31 14:57:50 veillard Exp $