deps/src/libxml2-2.9.1/doc/xmlio.html
| |
|
|
|
|
|
|
|
|
|
| Developer Menu | |
|
| API Indexes | |
|
| Related links | |
|
|
|
|
|
|
Table of Content:
The module xmlIO.h provides the interfaces to the libxml2 I/O system. This consists of 4 main parts:
xmlGetExternalEntityLoader() and xmlSetExternalEntityLoader(). Check the example.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 libxml2 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 trade-off). 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);
|
|
|
|
|