|
Packit Service |
a31ea6 |
|
|
Packit Service |
a31ea6 |
|
|
Packit Service |
a31ea6 |
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><link rel="SHORTCUT ICON" href="/favicon.ico" /><style type="text/css">
|
|
Packit Service |
a31ea6 |
TD {font-family: Verdana,Arial,Helvetica}
|
|
Packit Service |
a31ea6 |
BODY {font-family: Verdana,Arial,Helvetica; margin-top: 2em; margin-left: 0em; margin-right: 0em}
|
|
Packit Service |
a31ea6 |
H1 {font-family: Verdana,Arial,Helvetica}
|
|
Packit Service |
a31ea6 |
H2 {font-family: Verdana,Arial,Helvetica}
|
|
Packit Service |
a31ea6 |
H3 {font-family: Verdana,Arial,Helvetica}
|
|
Packit Service |
a31ea6 |
A:link, A:visited, A:active { text-decoration: underline }
|
|
Packit Service |
a31ea6 |
</style><title>I/O Interfaces</title></head><body bgcolor="#8b7765" text="#000000" link="#a06060" vlink="#000000"> | | The XML C parser and toolkit of GnomeI/O Interfaces |
|
|
<center>Developer Menu</center> | <form action="search.php" enctype="application/x-www-form-urlencoded" method="get"><input name="query" type="text" size="20" value="" /><input name="submit" type="submit" value="Search ..." /></form> |
<center>API Indexes</center> | |
<center>Related links</center> | |
|
| |
|
|
|
Packit Service |
a31ea6 |
General overview
|
|
Packit Service |
a31ea6 |
The basic buffer type
|
|
Packit Service |
a31ea6 |
Input I/O handlers
|
|
Packit Service |
a31ea6 |
Output I/O handlers
|
|
Packit Service |
a31ea6 |
The entities loader
|
|
Packit Service |
a31ea6 |
Example of customized I/O
|
|
Packit Service |
a31ea6 |
The module xmlIO.h provides
|
|
Packit Service |
a31ea6 |
the interfaces to the libxml2 I/O system. This consists of 4 main parts:
|
|
Packit Service |
a31ea6 |
Entities loader, this is a routine which tries to fetch the entities
|
|
Packit Service |
a31ea6 |
(files) based on their PUBLIC and SYSTEM identifiers. The default loader
|
|
Packit Service |
a31ea6 |
don't look at the public identifier since libxml2 do not maintain a
|
|
Packit Service |
a31ea6 |
catalog. You can redefine you own entity loader by using
|
|
Packit Service |
a31ea6 |
xmlGetExternalEntityLoader() and
|
|
Packit Service |
a31ea6 |
xmlSetExternalEntityLoader() . Check the
|
|
Packit Service |
a31ea6 |
example.
|
|
Packit Service |
a31ea6 |
Input I/O buffers which are a commodity structure used by the parser(s)
|
|
Packit Service |
a31ea6 |
input layer to handle fetching the information to feed the parser. This
|
|
Packit Service |
a31ea6 |
provides buffering and is also a placeholder where the encoding
|
|
Packit Service |
a31ea6 |
converters to UTF8 are piggy-backed.
|
|
Packit Service |
a31ea6 |
Output I/O buffers are similar to the Input ones and fulfill similar
|
|
Packit Service |
a31ea6 |
task but when generating a serialization from a tree.
|
|
Packit Service |
a31ea6 |
A mechanism to register sets of I/O callbacks and associate them with
|
|
Packit Service |
a31ea6 |
specific naming schemes like the protocol part of the URIs.
|
|
Packit Service |
a31ea6 |
This affect the default I/O operations and allows to use specific I/O
|
|
Packit Service |
a31ea6 |
handlers for certain names.
|
|
Packit Service |
a31ea6 |
|
|
Packit Service |
a31ea6 |
The general mechanism used when loading http://rpmfind.net/xml.html for
|
|
Packit Service |
a31ea6 |
example in the HTML parser is the following:
|
|
Packit Service |
a31ea6 |
The default entity loader calls xmlNewInputFromFile() with
|
|
Packit Service |
a31ea6 |
the parsing context and the URI string.
|
|
Packit Service |
a31ea6 |
the URI string is checked against the existing registered handlers
|
|
Packit Service |
a31ea6 |
using their match() callback function, if the HTTP module was compiled
|
|
Packit Service |
a31ea6 |
in, it is registered and its match() function will succeeds
|
|
Packit Service |
a31ea6 |
the open() function of the handler is called and if successful will
|
|
Packit Service |
a31ea6 |
return an I/O Input buffer
|
|
Packit Service |
a31ea6 |
the parser will the start reading from this buffer and progressively
|
|
Packit Service |
a31ea6 |
fetch information from the resource, calling the read() function of the
|
|
Packit Service |
a31ea6 |
handler until the resource is exhausted
|
|
Packit Service |
a31ea6 |
if an encoding change is detected it will be installed on the input
|
|
Packit Service |
a31ea6 |
buffer, providing buffering and efficient use of the conversion
|
|
Packit Service |
a31ea6 |
routines
|
|
Packit Service |
a31ea6 |
once the parser has finished, the close() function of the handler is
|
|
Packit Service |
a31ea6 |
called once and the Input buffer and associated resources are
|
|
Packit Service |
a31ea6 |
deallocated.
|
|
Packit Service |
a31ea6 |
The user defined callbacks are checked first to allow overriding of the
|
|
Packit Service |
a31ea6 |
default libxml2 I/O routines.All the buffer manipulation handling is done using the
|
|
Packit Service |
a31ea6 |
xmlBuffer type define in tree.h which is a
|
|
Packit Service |
a31ea6 |
resizable memory buffer. The buffer allocation strategy can be selected to be
|
|
Packit Service |
a31ea6 |
either best-fit or use an exponential doubling one (CPU vs. memory use
|
|
Packit Service |
a31ea6 |
trade-off). The values are XML_BUFFER_ALLOC_EXACT and
|
|
Packit Service |
a31ea6 |
XML_BUFFER_ALLOC_DOUBLEIT , and can be set individually or on a
|
|
Packit Service |
a31ea6 |
system wide basis using xmlBufferSetAllocationScheme() . A number
|
|
Packit Service |
a31ea6 |
of functions allows to manipulate buffers with names starting with the
|
|
Packit Service |
a31ea6 |
xmlBuffer... prefix.An Input I/O handler is a simple structure
|
|
Packit Service |
a31ea6 |
xmlParserInputBuffer containing a context associated to the
|
|
Packit Service |
a31ea6 |
resource (file descriptor, or pointer to a protocol handler), the read() and
|
|
Packit Service |
a31ea6 |
close() callbacks to use and an xmlBuffer. And extra xmlBuffer and a charset
|
|
Packit Service |
a31ea6 |
encoding handler are also present to support charset conversion when
|
|
Packit Service |
a31ea6 |
needed.An Output handler xmlOutputBuffer is completely similar to an
|
|
Packit Service |
a31ea6 |
Input one except the callbacks are write() and close().The entity loader resolves requests for new entities and create inputs for
|
|
Packit Service |
a31ea6 |
the parser. Creating an input from a filename or an URI string is done
|
|
Packit Service |
a31ea6 |
through the xmlNewInputFromFile() routine. The default entity loader do not
|
|
Packit Service |
a31ea6 |
handle the PUBLIC identifier associated with an entity (if any). So it just
|
|
Packit Service |
a31ea6 |
calls xmlNewInputFromFile() with the SYSTEM identifier (which is mandatory in
|
|
Packit Service |
a31ea6 |
XML).If you want to hook up a catalog mechanism then you simply need to
|
|
Packit Service |
a31ea6 |
override the default entity loader, here is an example:#include <libxml/xmlIO.h>
|
|
Packit Service |
a31ea6 |
|
|
Packit Service |
a31ea6 |
xmlExternalEntityLoader defaultLoader = NULL;
|
|
Packit Service |
a31ea6 |
|
|
Packit Service |
a31ea6 |
xmlParserInputPtr
|
|
Packit Service |
a31ea6 |
xmlMyExternalEntityLoader(const char *URL, const char *ID,
|
|
Packit Service |
a31ea6 |
xmlParserCtxtPtr ctxt) {
|
|
Packit Service |
a31ea6 |
xmlParserInputPtr ret;
|
|
Packit Service |
a31ea6 |
const char *fileID = NULL;
|
|
Packit Service |
a31ea6 |
/* lookup for the fileID depending on ID */
|
|
Packit Service |
a31ea6 |
|
|
Packit Service |
a31ea6 |
ret = xmlNewInputFromFile(ctxt, fileID);
|
|
Packit Service |
a31ea6 |
if (ret != NULL)
|
|
Packit Service |
a31ea6 |
return(ret);
|
|
Packit Service |
a31ea6 |
if (defaultLoader != NULL)
|
|
Packit Service |
a31ea6 |
ret = defaultLoader(URL, ID, ctxt);
|
|
Packit Service |
a31ea6 |
return(ret);
|
|
Packit Service |
a31ea6 |
}
|
|
Packit Service |
a31ea6 |
|
|
Packit Service |
a31ea6 |
int main(..) {
|
|
Packit Service |
a31ea6 |
...
|
|
Packit Service |
a31ea6 |
|
|
Packit Service |
a31ea6 |
/*
|
|
Packit Service |
a31ea6 |
* Install our own entity loader
|
|
Packit Service |
a31ea6 |
*/
|
|
Packit Service |
a31ea6 |
defaultLoader = xmlGetExternalEntityLoader();
|
|
Packit Service |
a31ea6 |
xmlSetExternalEntityLoader(xmlMyExternalEntityLoader);
|
|
Packit Service |
a31ea6 |
|
|
Packit Service |
a31ea6 |
...
|
|
Packit Service |
a31ea6 |
}This example come from a
|
|
Packit Service |
a31ea6 |
real use case, xmlDocDump() closes the FILE * passed by the application
|
|
Packit Service |
a31ea6 |
and this was a problem. The solution was to redefine a
|
|
Packit Service |
a31ea6 |
new output handler with the closing call deactivated:
|
|
Packit Service |
a31ea6 |
First define a new I/O output allocator where the output don't close
|
|
Packit Service |
a31ea6 |
the file:
|
|
Packit Service |
a31ea6 |
xmlOutputBufferPtr
|
|
Packit Service |
a31ea6 |
xmlOutputBufferCreateOwn(FILE *file, xmlCharEncodingHandlerPtr encoder) {
|
|
Packit Service |
a31ea6 |
xmlOutputBufferPtr ret;
|
|
Packit Service |
a31ea6 |
|
|
Packit Service |
a31ea6 |
if (xmlOutputCallbackInitialized == 0)
|
|
Packit Service |
a31ea6 |
xmlRegisterDefaultOutputCallbacks();
|
|
Packit Service |
a31ea6 |
|
|
Packit Service |
a31ea6 |
if (file == NULL) return(NULL);
|
|
Packit Service |
a31ea6 |
ret = xmlAllocOutputBuffer(encoder);
|
|
Packit Service |
a31ea6 |
if (ret != NULL) {
|
|
Packit Service |
a31ea6 |
ret->context = file;
|
|
Packit Service |
a31ea6 |
ret->writecallback = xmlFileWrite;
|
|
Packit Service |
a31ea6 |
ret->closecallback = NULL; /* No close callback */
|
|
Packit Service |
a31ea6 |
}
|
|
Packit Service |
a31ea6 |
return(ret);
|
|
Packit Service |
a31ea6 |
}
|
|
Packit Service |
a31ea6 |
|
|
Packit Service |
a31ea6 |
And then use it to save the document:
|
|
Packit Service |
a31ea6 |
FILE *f;
|
|
Packit Service |
a31ea6 |
xmlOutputBufferPtr output;
|
|
Packit Service |
a31ea6 |
xmlDocPtr doc;
|
|
Packit Service |
a31ea6 |
int res;
|
|
Packit Service |
a31ea6 |
|
|
Packit Service |
a31ea6 |
f = ...
|
|
Packit Service |
a31ea6 |
doc = ....
|
|
Packit Service |
a31ea6 |
|
|
Packit Service |
a31ea6 |
output = xmlOutputBufferCreateOwn(f, NULL);
|
|
Packit Service |
a31ea6 |
res = xmlSaveFileTo(output, doc, NULL);
|
|
Packit Service |
a31ea6 |
|
|
Packit Service |
a31ea6 |
|
|
Packit Service |
a31ea6 |
Daniel Veillard </body></html>
|