mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-07-30 22:43:14 +03:00
updated the python bindings, added code for easier File I/O, and the
* python/generator.py python/libxml.c python/libxml.py python/libxml2-python-api.xml python/libxml2class.txt python/libxml_wrap.h python/types.c: updated the python bindings, added code for easier File I/O, and the ability to define a resolver from Python fixing bug #91635 * python/tests/Makefile.am python/tests/inbuf.py python/tests/outbuf.py python/tests/pushSAXhtml.py python/tests/resolver.py python/tests/serialize.py: updated and augmented the set of Python tests. Daniel
This commit is contained in:
12
ChangeLog
12
ChangeLog
@ -1,3 +1,15 @@
|
|||||||
|
Thu Sep 12 16:57:45 CEST 2002 Daniel Veillard <daniel@veillard.com>
|
||||||
|
|
||||||
|
* python/generator.py python/libxml.c python/libxml.py
|
||||||
|
python/libxml2-python-api.xml python/libxml2class.txt
|
||||||
|
python/libxml_wrap.h python/types.c: updated the python
|
||||||
|
bindings, added code for easier File I/O, and the ability to
|
||||||
|
define a resolver from Python fixing bug #91635
|
||||||
|
* python/tests/Makefile.am python/tests/inbuf.py
|
||||||
|
python/tests/outbuf.py python/tests/pushSAXhtml.py
|
||||||
|
python/tests/resolver.py python/tests/serialize.py: updated
|
||||||
|
and augmented the set of Python tests.
|
||||||
|
|
||||||
Tue Sep 10 21:05:28 CEST 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
|
Tue Sep 10 21:05:28 CEST 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
|
||||||
|
|
||||||
* win32/configure.js: added more readme info for the binary
|
* win32/configure.js: added more readme info for the binary
|
||||||
|
@ -268,6 +268,8 @@ py_types = {
|
|||||||
'xmlCatalogPtr': ('O', "catalog", "xmlCatalogPtr", "xmlCatalogPtr"),
|
'xmlCatalogPtr': ('O', "catalog", "xmlCatalogPtr", "xmlCatalogPtr"),
|
||||||
'FILE *': ('O', "File", "FILEPtr", "FILE *"),
|
'FILE *': ('O', "File", "FILEPtr", "FILE *"),
|
||||||
'xmlURIPtr': ('O', "URI", "xmlURIPtr", "xmlURIPtr"),
|
'xmlURIPtr': ('O', "URI", "xmlURIPtr", "xmlURIPtr"),
|
||||||
|
'xmlOutputBufferPtr': ('O', "outputBuffer", "xmlOutputBufferPtr", "xmlOutputBufferPtr"),
|
||||||
|
'xmlParserInputBufferPtr': ('O', "inputBuffer", "xmlParserInputBufferPtr", "xmlParserInputBufferPtr"),
|
||||||
}
|
}
|
||||||
|
|
||||||
py_return_types = {
|
py_return_types = {
|
||||||
@ -583,6 +585,8 @@ classes_type = {
|
|||||||
"htmlParserCtxt *": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"),
|
"htmlParserCtxt *": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"),
|
||||||
"xmlCatalogPtr": ("._o", "catalog(_obj=%s)", "catalog"),
|
"xmlCatalogPtr": ("._o", "catalog(_obj=%s)", "catalog"),
|
||||||
"xmlURIPtr": ("._o", "URI(_obj=%s)", "URI"),
|
"xmlURIPtr": ("._o", "URI(_obj=%s)", "URI"),
|
||||||
|
"xmlOutputBufferPtr": ("._o", "outputBuffer(_obj=%s)", "outputBuffer"),
|
||||||
|
"xmlParserInputBufferPtr": ("._o", "inputBuffer(_obj=%s)", "inputBuffer"),
|
||||||
}
|
}
|
||||||
|
|
||||||
converter_type = {
|
converter_type = {
|
||||||
@ -600,11 +604,15 @@ classes_ancestor = {
|
|||||||
"xmlEntity" : "xmlNode",
|
"xmlEntity" : "xmlNode",
|
||||||
"xmlElement" : "xmlNode",
|
"xmlElement" : "xmlNode",
|
||||||
"xmlAttribute" : "xmlNode",
|
"xmlAttribute" : "xmlNode",
|
||||||
|
"outputBuffer": "ioWriteWrapper",
|
||||||
|
"inputBuffer": "ioReadWrapper",
|
||||||
}
|
}
|
||||||
classes_destructors = {
|
classes_destructors = {
|
||||||
"parserCtxt": "xmlFreeParserCtxt",
|
"parserCtxt": "xmlFreeParserCtxt",
|
||||||
"catalog": "xmlFreeCatalog",
|
"catalog": "xmlFreeCatalog",
|
||||||
"URI": "xmlFreeURI",
|
"URI": "xmlFreeURI",
|
||||||
|
# "outputBuffer": "xmlOutputBufferClose",
|
||||||
|
"inputBuffer": "xmlFreeParserInputBuffer",
|
||||||
}
|
}
|
||||||
|
|
||||||
functions_noexcept = {
|
functions_noexcept = {
|
||||||
@ -647,6 +655,12 @@ def nameFixup(name, classe, type, file):
|
|||||||
elif name[0:11] == "xmlXPathSet" and file == "python_accessor":
|
elif name[0:11] == "xmlXPathSet" and file == "python_accessor":
|
||||||
func = name[8:]
|
func = name[8:]
|
||||||
func = string.lower(func[0:1]) + func[1:]
|
func = string.lower(func[0:1]) + func[1:]
|
||||||
|
elif name[0:15] == "xmlOutputBuffer" and file != "python":
|
||||||
|
func = name[15:]
|
||||||
|
func = string.lower(func[0:1]) + func[1:]
|
||||||
|
elif name[0:20] == "xmlParserInputBuffer" and file != "python":
|
||||||
|
func = name[20:]
|
||||||
|
func = string.lower(func[0:1]) + func[1:]
|
||||||
elif name[0:11] == "xmlACatalog":
|
elif name[0:11] == "xmlACatalog":
|
||||||
func = name[11:]
|
func = name[11:]
|
||||||
func = string.lower(func[0:1]) + func[1:]
|
func = string.lower(func[0:1]) + func[1:]
|
||||||
|
380
python/libxml.c
380
python/libxml.c
@ -12,6 +12,7 @@
|
|||||||
* daniel@veillard.com
|
* daniel@veillard.com
|
||||||
*/
|
*/
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
|
#include <fileobject.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <libxml/xmlmemory.h>
|
#include <libxml/xmlmemory.h>
|
||||||
#include <libxml/parser.h>
|
#include <libxml/parser.h>
|
||||||
@ -20,21 +21,30 @@
|
|||||||
#include <libxml/xmlerror.h>
|
#include <libxml/xmlerror.h>
|
||||||
#include <libxml/xpathInternals.h>
|
#include <libxml/xpathInternals.h>
|
||||||
#include <libxml/xmlmemory.h>
|
#include <libxml/xmlmemory.h>
|
||||||
|
#include <libxml/xmlIO.h>
|
||||||
#include "libxml_wrap.h"
|
#include "libxml_wrap.h"
|
||||||
#include "libxml2-py.h"
|
#include "libxml2-py.h"
|
||||||
|
|
||||||
/* #define DEBUG */
|
/* #define DEBUG */
|
||||||
|
|
||||||
/* #define DEBUG_SAX */
|
/* #define DEBUG_SAX */
|
||||||
|
|
||||||
/* #define DEBUG_XPATH */
|
/* #define DEBUG_XPATH */
|
||||||
|
|
||||||
/* #define DEBUG_ERROR */
|
/* #define DEBUG_ERROR */
|
||||||
|
|
||||||
/* #define DEBUG_MEMORY */
|
/* #define DEBUG_MEMORY */
|
||||||
|
/* #define DEBUG_FILES */
|
||||||
|
/* #define DEBUG_LOADER */
|
||||||
|
|
||||||
void initlibxml2mod(void);
|
void initlibxml2mod(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO:
|
||||||
|
*
|
||||||
|
* macro to flag unimplemented blocks
|
||||||
|
*/
|
||||||
|
#define TODO \
|
||||||
|
xmlGenericError(xmlGenericErrorContext, \
|
||||||
|
"Unimplemented block at %s:%d\n", \
|
||||||
|
__FILE__, __LINE__);
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* *
|
* *
|
||||||
* Memory debug interface *
|
* Memory debug interface *
|
||||||
@ -123,6 +133,363 @@ libxml_xmlDumpMemory(ATTRIBUTE_UNUSED PyObject * self,
|
|||||||
return (Py_None);
|
return (Py_None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* *
|
||||||
|
* Handling Python FILE I/O at the C level *
|
||||||
|
* The raw I/O attack diectly the File objects, while the *
|
||||||
|
* other routines address the ioWrapper instance instead *
|
||||||
|
* *
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlPythonFileCloseUnref:
|
||||||
|
* @context: the I/O context
|
||||||
|
*
|
||||||
|
* Close an I/O channel
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
xmlPythonFileCloseRaw (void * context) {
|
||||||
|
PyObject *file, *ret;
|
||||||
|
|
||||||
|
#ifdef DEBUG_FILES
|
||||||
|
printf("xmlPythonFileCloseUnref\n");
|
||||||
|
#endif
|
||||||
|
file = (PyObject *) context;
|
||||||
|
if (file == NULL) return(-1);
|
||||||
|
ret = PyEval_CallMethod(file, "close", "()");
|
||||||
|
if (ret != NULL) {
|
||||||
|
Py_DECREF(ret);
|
||||||
|
}
|
||||||
|
Py_DECREF(file);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlPythonFileReadRaw:
|
||||||
|
* @context: the I/O context
|
||||||
|
* @buffer: where to drop data
|
||||||
|
* @len: number of bytes to write
|
||||||
|
*
|
||||||
|
* Read @len bytes to @buffer from the Python file in the I/O channel
|
||||||
|
*
|
||||||
|
* Returns the number of bytes read
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
xmlPythonFileReadRaw (void * context, char * buffer, int len) {
|
||||||
|
PyObject *file;
|
||||||
|
PyObject *ret;
|
||||||
|
int lenread = -1;
|
||||||
|
char *data;
|
||||||
|
|
||||||
|
#ifdef DEBUG_FILES
|
||||||
|
printf("xmlPythonFileReadRaw: %d\n", len);
|
||||||
|
#endif
|
||||||
|
file = (PyObject *) context;
|
||||||
|
if (file == NULL) return(-1);
|
||||||
|
ret = PyEval_CallMethod(file, "read", "(i)", len);
|
||||||
|
if (ret == NULL) {
|
||||||
|
printf("xmlPythonFileReadRaw: result is NULL\n");
|
||||||
|
return(-1);
|
||||||
|
} else if (PyString_Check(ret)) {
|
||||||
|
lenread = PyString_Size(ret);
|
||||||
|
data = PyString_AsString(ret);
|
||||||
|
if (lenread > len)
|
||||||
|
memcpy(buffer, data, len);
|
||||||
|
else
|
||||||
|
memcpy(buffer, data, lenread);
|
||||||
|
Py_DECREF(ret);
|
||||||
|
} else {
|
||||||
|
printf("xmlPythonFileReadRaw: result is not a String\n");
|
||||||
|
Py_DECREF(ret);
|
||||||
|
}
|
||||||
|
return(lenread);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlPythonFileRead:
|
||||||
|
* @context: the I/O context
|
||||||
|
* @buffer: where to drop data
|
||||||
|
* @len: number of bytes to write
|
||||||
|
*
|
||||||
|
* Read @len bytes to @buffer from the I/O channel.
|
||||||
|
*
|
||||||
|
* Returns the number of bytes read
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
xmlPythonFileRead (void * context, char * buffer, int len) {
|
||||||
|
PyObject *file;
|
||||||
|
PyObject *ret;
|
||||||
|
int lenread = -1;
|
||||||
|
char *data;
|
||||||
|
|
||||||
|
#ifdef DEBUG_FILES
|
||||||
|
printf("xmlPythonFileRead: %d\n", len);
|
||||||
|
#endif
|
||||||
|
file = (PyObject *) context;
|
||||||
|
if (file == NULL) return(-1);
|
||||||
|
ret = PyEval_CallMethod(file, "io_read", "(i)", len);
|
||||||
|
if (ret == NULL) {
|
||||||
|
printf("xmlPythonFileRead: result is NULL\n");
|
||||||
|
return(-1);
|
||||||
|
} else if (PyString_Check(ret)) {
|
||||||
|
lenread = PyString_Size(ret);
|
||||||
|
data = PyString_AsString(ret);
|
||||||
|
if (lenread > len)
|
||||||
|
memcpy(buffer, data, len);
|
||||||
|
else
|
||||||
|
memcpy(buffer, data, lenread);
|
||||||
|
Py_DECREF(ret);
|
||||||
|
} else {
|
||||||
|
printf("xmlPythonFileRead: result is not a String\n");
|
||||||
|
Py_DECREF(ret);
|
||||||
|
}
|
||||||
|
return(lenread);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlFileWrite:
|
||||||
|
* @context: the I/O context
|
||||||
|
* @buffer: where to drop data
|
||||||
|
* @len: number of bytes to write
|
||||||
|
*
|
||||||
|
* Write @len bytes from @buffer to the I/O channel.
|
||||||
|
*
|
||||||
|
* Returns the number of bytes written
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
xmlPythonFileWrite (void * context, const char * buffer, int len) {
|
||||||
|
PyObject *file;
|
||||||
|
PyObject *string;
|
||||||
|
PyObject *ret;
|
||||||
|
int written = -1;
|
||||||
|
|
||||||
|
#ifdef DEBUG_FILES
|
||||||
|
printf("xmlPythonFileWrite: %d\n", len);
|
||||||
|
#endif
|
||||||
|
file = (PyObject *) context;
|
||||||
|
if (file == NULL) return(-1);
|
||||||
|
string = PyString_FromStringAndSize(buffer, len);
|
||||||
|
if (string == NULL) return(-1);
|
||||||
|
ret = PyEval_CallMethod(file, "io_write", "(O)", string);
|
||||||
|
Py_DECREF(string);
|
||||||
|
if (ret == NULL) {
|
||||||
|
printf("xmlPythonFileWrite: result is NULL\n");
|
||||||
|
return(-1);
|
||||||
|
} else if (PyInt_Check(ret)) {
|
||||||
|
written = (int) PyInt_AsLong(ret);
|
||||||
|
Py_DECREF(ret);
|
||||||
|
} else if (ret == Py_None) {
|
||||||
|
written = len;
|
||||||
|
Py_DECREF(ret);
|
||||||
|
} else {
|
||||||
|
printf("xmlPythonFileWrite: result is not an Int nor None\n");
|
||||||
|
Py_DECREF(ret);
|
||||||
|
}
|
||||||
|
return(written);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlPythonFileClose:
|
||||||
|
* @context: the I/O context
|
||||||
|
*
|
||||||
|
* Close an I/O channel
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
xmlPythonFileClose (void * context) {
|
||||||
|
PyObject *file, *ret;
|
||||||
|
|
||||||
|
#ifdef DEBUG_FILES
|
||||||
|
printf("xmlPythonFileClose\n");
|
||||||
|
#endif
|
||||||
|
file = (PyObject *) context;
|
||||||
|
if (file == NULL) return(-1);
|
||||||
|
ret = PyEval_CallMethod(file, "io_close", "()");
|
||||||
|
if (ret != NULL) {
|
||||||
|
Py_DECREF(ret);
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlOutputBufferCreatePythonFile:
|
||||||
|
* @file: a PyFile_Type
|
||||||
|
* @encoder: the encoding converter or NULL
|
||||||
|
*
|
||||||
|
* Create a buffered output for the progressive saving to a PyFile_Type
|
||||||
|
* buffered C I/O
|
||||||
|
*
|
||||||
|
* Returns the new parser output or NULL
|
||||||
|
*/
|
||||||
|
xmlOutputBufferPtr
|
||||||
|
xmlOutputBufferCreatePythonFile(PyObject *file,
|
||||||
|
xmlCharEncodingHandlerPtr encoder) {
|
||||||
|
xmlOutputBufferPtr ret;
|
||||||
|
|
||||||
|
if (file == NULL) return(NULL);
|
||||||
|
|
||||||
|
ret = xmlAllocOutputBuffer(encoder);
|
||||||
|
if (ret != NULL) {
|
||||||
|
ret->context = file;
|
||||||
|
/* Py_INCREF(file); */
|
||||||
|
ret->writecallback = xmlPythonFileWrite;
|
||||||
|
ret->closecallback = xmlPythonFileClose;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
libxml_xmlCreateOutputBuffer(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
|
||||||
|
PyObject *py_retval;
|
||||||
|
PyObject *file;
|
||||||
|
xmlChar *encoding;
|
||||||
|
xmlCharEncodingHandlerPtr handler = NULL;
|
||||||
|
xmlOutputBufferPtr buffer;
|
||||||
|
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, (char *)"Oz:xmlOutputBufferCreate",
|
||||||
|
&file, &encoding))
|
||||||
|
return(NULL);
|
||||||
|
if ((encoding != NULL) && (encoding[0] != 0)) {
|
||||||
|
handler = xmlFindCharEncodingHandler(encoding);
|
||||||
|
}
|
||||||
|
buffer = xmlOutputBufferCreatePythonFile(file, handler);
|
||||||
|
if (buffer == NULL)
|
||||||
|
printf("libxml_xmlCreateOutputBuffer: buffer == NULL\n");
|
||||||
|
py_retval = libxml_xmlOutputBufferPtrWrap(buffer);
|
||||||
|
return(py_retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlParserInputBufferCreatePythonFile:
|
||||||
|
* @file: a PyFile_Type
|
||||||
|
* @encoder: the encoding converter or NULL
|
||||||
|
*
|
||||||
|
* Create a buffered output for the progressive saving to a PyFile_Type
|
||||||
|
* buffered C I/O
|
||||||
|
*
|
||||||
|
* Returns the new parser output or NULL
|
||||||
|
*/
|
||||||
|
xmlParserInputBufferPtr
|
||||||
|
xmlParserInputBufferCreatePythonFile(PyObject *file,
|
||||||
|
xmlCharEncoding encoding) {
|
||||||
|
xmlParserInputBufferPtr ret;
|
||||||
|
|
||||||
|
if (file == NULL) return(NULL);
|
||||||
|
|
||||||
|
ret = xmlAllocParserInputBuffer(encoding);
|
||||||
|
if (ret != NULL) {
|
||||||
|
ret->context = file;
|
||||||
|
/* Py_INCREF(file); */
|
||||||
|
ret->readcallback = xmlPythonFileRead;
|
||||||
|
ret->closecallback = xmlPythonFileClose;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
libxml_xmlCreateInputBuffer(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
|
||||||
|
PyObject *py_retval;
|
||||||
|
PyObject *file;
|
||||||
|
xmlChar *encoding;
|
||||||
|
xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
|
||||||
|
xmlParserInputBufferPtr buffer;
|
||||||
|
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, (char *)"Oz:xmlParserInputBufferCreate",
|
||||||
|
&file, &encoding))
|
||||||
|
return(NULL);
|
||||||
|
if ((encoding != NULL) && (encoding[0] != 0)) {
|
||||||
|
enc = xmlParseCharEncoding(encoding);
|
||||||
|
}
|
||||||
|
buffer = xmlParserInputBufferCreatePythonFile(file, enc);
|
||||||
|
if (buffer == NULL)
|
||||||
|
printf("libxml_xmlParserInputBufferCreate: buffer == NULL\n");
|
||||||
|
py_retval = libxml_xmlParserInputBufferPtrWrap(buffer);
|
||||||
|
return(py_retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* *
|
||||||
|
* Providing the resolver at the Python level *
|
||||||
|
* *
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
|
static xmlExternalEntityLoader defaultExternalEntityLoader = NULL;
|
||||||
|
static PyObject *pythonExternalEntityLoaderObjext;
|
||||||
|
|
||||||
|
static xmlParserInputPtr
|
||||||
|
pythonExternalEntityLoader(const char *URL, const char *ID,
|
||||||
|
xmlParserCtxtPtr ctxt) {
|
||||||
|
xmlParserInputPtr result = NULL;
|
||||||
|
if (pythonExternalEntityLoaderObjext != NULL) {
|
||||||
|
PyObject *ret;
|
||||||
|
PyObject *ctxtobj;
|
||||||
|
|
||||||
|
ctxtobj = libxml_xmlParserCtxtPtrWrap(ctxt);
|
||||||
|
#ifdef DEBUG_LOADER
|
||||||
|
printf("pythonExternalEntityLoader: ready to call\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ret = PyObject_CallFunction(pythonExternalEntityLoaderObjext,
|
||||||
|
"(ssO)", URL, ID, ctxtobj);
|
||||||
|
#ifdef DEBUG_LOADER
|
||||||
|
printf("pythonExternalEntityLoader: result ");
|
||||||
|
PyObject_Print(ret, stdout, 0);
|
||||||
|
printf("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ret != NULL) {
|
||||||
|
if (PyObject_HasAttrString(ret, "read")) {
|
||||||
|
xmlParserInputBufferPtr buf;
|
||||||
|
|
||||||
|
buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
|
||||||
|
if (buf != NULL) {
|
||||||
|
buf->context = ret;
|
||||||
|
buf->readcallback = xmlPythonFileReadRaw;
|
||||||
|
buf->closecallback = xmlPythonFileCloseRaw;
|
||||||
|
result = xmlNewIOInputStream(ctxt, buf,
|
||||||
|
XML_CHAR_ENCODING_NONE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("pythonExternalEntityLoader: can't read\n");
|
||||||
|
}
|
||||||
|
if (result == NULL) {
|
||||||
|
Py_DECREF(ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((result == NULL) && (defaultExternalEntityLoader != NULL)) {
|
||||||
|
result = defaultExternalEntityLoader(URL, ID, ctxt);
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
libxml_xmlSetEntityLoader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
|
||||||
|
PyObject *py_retval;
|
||||||
|
PyObject *loader;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, (char *)"O:libxml_xmlSetEntityLoader",
|
||||||
|
&loader))
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
#ifdef DEBUG_LOADER
|
||||||
|
printf("libxml_xmlSetEntityLoader\n");
|
||||||
|
#endif
|
||||||
|
if (defaultExternalEntityLoader == NULL)
|
||||||
|
defaultExternalEntityLoader = xmlGetExternalEntityLoader();
|
||||||
|
|
||||||
|
pythonExternalEntityLoaderObjext = loader;
|
||||||
|
xmlSetExternalEntityLoader(pythonExternalEntityLoader);
|
||||||
|
|
||||||
|
py_retval = PyInt_FromLong(0);
|
||||||
|
return(py_retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* *
|
* *
|
||||||
* Handling SAX/xmllib/sgmlop callback interfaces *
|
* Handling SAX/xmllib/sgmlop callback interfaces *
|
||||||
@ -1821,6 +2188,9 @@ static PyMethodDef libxmlMethods[] = {
|
|||||||
{(char *) "xmlNewNode", libxml_xmlNewNode, METH_VARARGS, NULL},
|
{(char *) "xmlNewNode", libxml_xmlNewNode, METH_VARARGS, NULL},
|
||||||
{(char *) "serializeNode", libxml_serializeNode, METH_VARARGS, NULL},
|
{(char *) "serializeNode", libxml_serializeNode, METH_VARARGS, NULL},
|
||||||
{(char *) "saveNodeTo", libxml_saveNodeTo, METH_VARARGS, NULL},
|
{(char *) "saveNodeTo", libxml_saveNodeTo, METH_VARARGS, NULL},
|
||||||
|
{(char *) "outputBufferCreate", libxml_xmlCreateOutputBuffer, METH_VARARGS, NULL},
|
||||||
|
{(char *) "inputBufferCreate", libxml_xmlCreateInputBuffer, METH_VARARGS, NULL},
|
||||||
|
{(char *) "setEntityLoader", libxml_xmlSetEntityLoader, METH_VARARGS, NULL},
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1836,6 +2206,8 @@ initlibxml2mod(void)
|
|||||||
|
|
||||||
if (initialized != 0)
|
if (initialized != 0)
|
||||||
return;
|
return;
|
||||||
|
xmlRegisterDefaultOutputCallbacks();
|
||||||
|
xmlRegisterDefaultInputCallbacks();
|
||||||
m = Py_InitModule((char *) "libxml2mod", libxmlMethods);
|
m = Py_InitModule((char *) "libxml2mod", libxmlMethods);
|
||||||
initialized = 1;
|
initialized = 1;
|
||||||
libxml_xmlErrorInitialize();
|
libxml_xmlErrorInitialize();
|
||||||
|
@ -27,6 +27,74 @@ class xpathError:
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.msg
|
return self.msg
|
||||||
|
|
||||||
|
class ioWrapper:
|
||||||
|
def __init__(self, _obj):
|
||||||
|
self.__io = _obj
|
||||||
|
self._o = None
|
||||||
|
|
||||||
|
def io_close(self):
|
||||||
|
if self.__io == None:
|
||||||
|
return(-1)
|
||||||
|
self.__io.close()
|
||||||
|
self.__io = None
|
||||||
|
return(0)
|
||||||
|
|
||||||
|
def io_flush(self):
|
||||||
|
if self.__io == None:
|
||||||
|
return(-1)
|
||||||
|
self.__io.flush()
|
||||||
|
return(0)
|
||||||
|
|
||||||
|
def io_read(self, len = -1):
|
||||||
|
if self.__io == None:
|
||||||
|
return(-1)
|
||||||
|
if len < 0:
|
||||||
|
return(self.__io.read())
|
||||||
|
return(self.__io.read(len))
|
||||||
|
|
||||||
|
def io_write(self, str, len = -1):
|
||||||
|
if self.__io == None:
|
||||||
|
return(-1)
|
||||||
|
if len < 0:
|
||||||
|
return(self.__io.write(str))
|
||||||
|
return(self.__io.write(str, len))
|
||||||
|
|
||||||
|
class ioReadWrapper(ioWrapper):
|
||||||
|
def __init__(self, _obj, enc = ""):
|
||||||
|
ioWrapper.__init__(self, _obj)
|
||||||
|
self._o = libxml2mod.xmlCreateInputBuffer(self, enc)
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
print "__del__"
|
||||||
|
self.io_close()
|
||||||
|
if self._o != None:
|
||||||
|
libxml2mod.xmlFreeParserInputBuffer(self._o)
|
||||||
|
self._o = None
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
self.io_close()
|
||||||
|
if self._o != None:
|
||||||
|
libxml2mod.xmlFreeParserInputBuffer(self._o)
|
||||||
|
self._o = None
|
||||||
|
|
||||||
|
class ioWriteWrapper(ioWrapper):
|
||||||
|
def __init__(self, _obj, enc = ""):
|
||||||
|
ioWrapper.__init__(self, _obj)
|
||||||
|
self._o = libxml2mod.xmlCreateOutputBuffer(self, enc)
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
print "__del__"
|
||||||
|
self.io_close()
|
||||||
|
if self._o != None:
|
||||||
|
libxml2mod.xmlOutputBufferClose(self._o)
|
||||||
|
self._o = None
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
self.io_close()
|
||||||
|
if self._o != None:
|
||||||
|
libxml2mod.xmlOutputBufferClose(self._o)
|
||||||
|
self._o = None
|
||||||
|
|
||||||
#
|
#
|
||||||
# Example of a class to handle SAX events
|
# Example of a class to handle SAX events
|
||||||
#
|
#
|
||||||
|
@ -50,6 +50,23 @@
|
|||||||
<arg name='URI' type='xmlChar *' info='The URI of the resource'/>
|
<arg name='URI' type='xmlChar *' info='The URI of the resource'/>
|
||||||
<arg name='encoding' type='const char *' info='encoding or None'/>
|
<arg name='encoding' type='const char *' info='encoding or None'/>
|
||||||
</function>
|
</function>
|
||||||
|
<function name='xmlCreateOutputBuffer' file='python'>
|
||||||
|
<info>Create a libxml2 output buffer from a Python file</info>
|
||||||
|
<return type='xmlOutputBufferPtr' info="the output buffer"/>
|
||||||
|
<arg name='file' type='pythonObject' info='the Python file'/>
|
||||||
|
<arg name='encoding' type='xmlChar *' info='an optionnal encoding'/>
|
||||||
|
</function>
|
||||||
|
<function name='xmlCreateInputBuffer' file='python'>
|
||||||
|
<info>Create a libxml2 input buffer from a Python file</info>
|
||||||
|
<return type='xmlParserInputBufferPtr' info="the input buffer"/>
|
||||||
|
<arg name='file' type='pythonObject' info='the Python file'/>
|
||||||
|
<arg name='encoding' type='xmlChar *' info='an optionnal encoding'/>
|
||||||
|
</function>
|
||||||
|
<function name='xmlSetEntityLoader' file='python'>
|
||||||
|
<info>Set the entity resolver as a python function</info>
|
||||||
|
<return type='int' info="0 in case of success, -1 for error"/>
|
||||||
|
<arg name='resolver' type='pythonObject' info='the Python function'/>
|
||||||
|
</function>
|
||||||
<!-- xmlParserCtxtPtr accessors -->
|
<!-- xmlParserCtxtPtr accessors -->
|
||||||
<function name='xmlParserGetDoc' file='python_accessor'>
|
<function name='xmlParserGetDoc' file='python_accessor'>
|
||||||
<info>Get the document tree from a parser context.</info>
|
<info>Get the document tree from a parser context.</info>
|
||||||
|
@ -114,6 +114,8 @@ nodePush()
|
|||||||
|
|
||||||
# functions from module python
|
# functions from module python
|
||||||
SAXParseFile()
|
SAXParseFile()
|
||||||
|
createInputBuffer()
|
||||||
|
createOutputBuffer()
|
||||||
createPushParser()
|
createPushParser()
|
||||||
debugMemory()
|
debugMemory()
|
||||||
dumpMemory()
|
dumpMemory()
|
||||||
@ -121,6 +123,7 @@ htmlCreatePushParser()
|
|||||||
htmlSAXParseFile()
|
htmlSAXParseFile()
|
||||||
newNode()
|
newNode()
|
||||||
registerErrorHandler()
|
registerErrorHandler()
|
||||||
|
setEntityLoader()
|
||||||
|
|
||||||
# functions from module tree
|
# functions from module tree
|
||||||
compressMode()
|
compressMode()
|
||||||
@ -276,10 +279,13 @@ Class xmlDoc(xmlNode)
|
|||||||
htmlIsAutoClosed()
|
htmlIsAutoClosed()
|
||||||
|
|
||||||
# functions from module HTMLtree
|
# functions from module HTMLtree
|
||||||
|
htmlDocContentDumpFormatOutput()
|
||||||
|
htmlDocContentDumpOutput()
|
||||||
htmlDocDump()
|
htmlDocDump()
|
||||||
htmlGetMetaEncoding()
|
htmlGetMetaEncoding()
|
||||||
htmlNodeDumpFile()
|
htmlNodeDumpFile()
|
||||||
htmlNodeDumpFileFormat()
|
htmlNodeDumpFileFormat()
|
||||||
|
htmlNodeDumpFormatOutput()
|
||||||
htmlSaveFile()
|
htmlSaveFile()
|
||||||
htmlSaveFileEnc()
|
htmlSaveFileEnc()
|
||||||
htmlSaveFileFormat()
|
htmlSaveFileFormat()
|
||||||
@ -323,10 +329,13 @@ Class xmlDoc(xmlNode)
|
|||||||
newDtd()
|
newDtd()
|
||||||
newGlobalNs()
|
newGlobalNs()
|
||||||
newReference()
|
newReference()
|
||||||
|
nodeDumpOutput()
|
||||||
saveFile()
|
saveFile()
|
||||||
saveFileEnc()
|
saveFileEnc()
|
||||||
|
saveFileTo()
|
||||||
saveFormatFile()
|
saveFormatFile()
|
||||||
saveFormatFileEnc()
|
saveFormatFileEnc()
|
||||||
|
saveFormatFileTo()
|
||||||
setDocCompressMode()
|
setDocCompressMode()
|
||||||
stringGetNodeList()
|
stringGetNodeList()
|
||||||
stringLenGetNodeList()
|
stringLenGetNodeList()
|
||||||
@ -510,6 +519,15 @@ Class parserCtxt()
|
|||||||
stringDecodeEntities()
|
stringDecodeEntities()
|
||||||
|
|
||||||
|
|
||||||
|
Class outputBuffer(ioWriteWrapper)
|
||||||
|
|
||||||
|
# functions from module xmlIO
|
||||||
|
close()
|
||||||
|
flush()
|
||||||
|
write()
|
||||||
|
writeString()
|
||||||
|
|
||||||
|
|
||||||
Class xmlElement(xmlNode)
|
Class xmlElement(xmlNode)
|
||||||
|
|
||||||
|
|
||||||
@ -584,3 +602,12 @@ Class xpathContext()
|
|||||||
xpathRegisteredVariablesCleanup()
|
xpathRegisteredVariablesCleanup()
|
||||||
xpathVariableLookup()
|
xpathVariableLookup()
|
||||||
xpathVariableLookupNS()
|
xpathVariableLookupNS()
|
||||||
|
|
||||||
|
|
||||||
|
Class inputBuffer(ioReadWrapper)
|
||||||
|
|
||||||
|
# functions from module xmlIO
|
||||||
|
freeParserInputBuffer()
|
||||||
|
grow()
|
||||||
|
push()
|
||||||
|
read()
|
||||||
|
@ -58,6 +58,22 @@ typedef struct {
|
|||||||
#define PyURI_Get(v) (((v) == Py_None) ? NULL : \
|
#define PyURI_Get(v) (((v) == Py_None) ? NULL : \
|
||||||
(((PyURI_Object *)(v))->obj))
|
(((PyURI_Object *)(v))->obj))
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PyObject_HEAD
|
||||||
|
xmlOutputBufferPtr obj;
|
||||||
|
} PyoutputBuffer_Object;
|
||||||
|
|
||||||
|
#define PyoutputBuffer_Get(v) (((v) == Py_None) ? NULL : \
|
||||||
|
(((PyURI_Object *)(v))->obj))
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PyObject_HEAD
|
||||||
|
xmlParserInputBufferPtr obj;
|
||||||
|
} PyinputBuffer_Object;
|
||||||
|
|
||||||
|
#define PyinputBuffer_Get(v) (((v) == Py_None) ? NULL : \
|
||||||
|
(((PyURI_Object *)(v))->obj))
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
xmlURIPtr obj;
|
xmlURIPtr obj;
|
||||||
@ -89,5 +105,7 @@ PyObject * libxml_xmlXPathParserContextPtrWrap(xmlXPathParserContextPtr ctxt);
|
|||||||
PyObject * libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj);
|
PyObject * libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj);
|
||||||
PyObject * libxml_xmlCatalogPtrWrap(xmlCatalogPtr obj);
|
PyObject * libxml_xmlCatalogPtrWrap(xmlCatalogPtr obj);
|
||||||
PyObject * libxml_xmlURIPtrWrap(xmlURIPtr uri);
|
PyObject * libxml_xmlURIPtrWrap(xmlURIPtr uri);
|
||||||
|
PyObject * libxml_xmlOutputBufferPtrWrap(xmlOutputBufferPtr buffer);
|
||||||
|
PyObject * libxml_xmlParserInputBufferPtrWrap(xmlParserInputBufferPtr buffer);
|
||||||
|
|
||||||
xmlXPathObjectPtr libxml_xmlXPathObjectPtrConvert(PyObject * obj);
|
xmlXPathObjectPtr libxml_xmlXPathObjectPtrConvert(PyObject * obj);
|
||||||
|
@ -15,7 +15,10 @@ PYTESTS= \
|
|||||||
tstURI.py \
|
tstURI.py \
|
||||||
cutnpaste.py\
|
cutnpaste.py\
|
||||||
xpathret.py \
|
xpathret.py \
|
||||||
xpath.py
|
xpath.py \
|
||||||
|
outbuf.py \
|
||||||
|
inbuf.py \
|
||||||
|
resolver.py
|
||||||
|
|
||||||
XMLS= \
|
XMLS= \
|
||||||
tst.xml \
|
tst.xml \
|
||||||
|
25
python/tests/inbuf.py
Executable file
25
python/tests/inbuf.py
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/python -u
|
||||||
|
import sys
|
||||||
|
import libxml2
|
||||||
|
import StringIO
|
||||||
|
|
||||||
|
# Memory debug specific
|
||||||
|
libxml2.debugMemory(1)
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
while i < 5000:
|
||||||
|
f = StringIO.StringIO("foobar")
|
||||||
|
buf = libxml2.inputBuffer(f)
|
||||||
|
i = i + 1
|
||||||
|
|
||||||
|
del f
|
||||||
|
del buf
|
||||||
|
|
||||||
|
# Memory debug specific
|
||||||
|
libxml2.cleanupParser()
|
||||||
|
if libxml2.debugMemory(1) == 0:
|
||||||
|
print "OK"
|
||||||
|
else:
|
||||||
|
print "Memory leak %d bytes" % (libxml2.debugMemory(1))
|
||||||
|
libxml2.dumpMemory()
|
||||||
|
|
33
python/tests/outbuf.py
Executable file
33
python/tests/outbuf.py
Executable file
@ -0,0 +1,33 @@
|
|||||||
|
#!/usr/bin/python -u
|
||||||
|
import sys
|
||||||
|
import libxml2
|
||||||
|
import StringIO
|
||||||
|
|
||||||
|
print "Skipped"
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Memory debug specific
|
||||||
|
libxml2.debugMemory(1)
|
||||||
|
|
||||||
|
#f = open('res', 'w')
|
||||||
|
f = StringIO.StringIO()
|
||||||
|
buf = libxml2.createOutputBuffer(f, "ISO-8859-1")
|
||||||
|
buf.write(3, "foo")
|
||||||
|
buf.writeString("bar")
|
||||||
|
buf.close()
|
||||||
|
del buf
|
||||||
|
|
||||||
|
if f.getvalue() != "foobar":
|
||||||
|
print "Failed to save to StringIO"
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
del f
|
||||||
|
|
||||||
|
# Memory debug specific
|
||||||
|
libxml2.cleanupParser()
|
||||||
|
if libxml2.debugMemory(1) == 0:
|
||||||
|
print "OK"
|
||||||
|
else:
|
||||||
|
print "Memory leak %d bytes" % (libxml2.debugMemory(1))
|
||||||
|
libxml2.dumpMemory()
|
||||||
|
|
@ -49,7 +49,8 @@ chunk = "ar</foo>"
|
|||||||
ctxt.htmlParseChunk(chunk, len(chunk), 1)
|
ctxt.htmlParseChunk(chunk, len(chunk), 1)
|
||||||
ctxt=None
|
ctxt=None
|
||||||
|
|
||||||
reference = "startDocument:startElement foo {'url': 'tst'}:characters: bar:endElement foo:endDocument:"
|
reference = """startDocument:startElement html None:startElement body None:startElement foo {'url': 'tst'}:error: Tag foo invalid
|
||||||
|
:characters: bar:endElement foo:endElement body:endElement html:endDocument:"""
|
||||||
if log != reference:
|
if log != reference:
|
||||||
print "Error got: %s" % log
|
print "Error got: %s" % log
|
||||||
print "Exprected: %s" % reference
|
print "Exprected: %s" % reference
|
||||||
|
39
python/tests/resolver.py
Executable file
39
python/tests/resolver.py
Executable file
@ -0,0 +1,39 @@
|
|||||||
|
#!/usr/bin/python -u
|
||||||
|
import sys
|
||||||
|
import libxml2
|
||||||
|
import StringIO
|
||||||
|
|
||||||
|
# Memory debug specific
|
||||||
|
libxml2.debugMemory(1)
|
||||||
|
|
||||||
|
def myResolver(URL, ID, ctxt):
|
||||||
|
return(StringIO.StringIO("<foo/>"))
|
||||||
|
|
||||||
|
libxml2.setEntityLoader(myResolver)
|
||||||
|
|
||||||
|
doc = libxml2.parseFile("doesnotexist.xml")
|
||||||
|
root = doc.children
|
||||||
|
if root.name != "foo":
|
||||||
|
print "root element name error"
|
||||||
|
sys.exit(1)
|
||||||
|
doc.freeDoc()
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
while i < 5000:
|
||||||
|
doc = libxml2.parseFile("doesnotexist.xml")
|
||||||
|
root = doc.children
|
||||||
|
if root.name != "foo":
|
||||||
|
print "root element name error"
|
||||||
|
sys.exit(1)
|
||||||
|
doc.freeDoc()
|
||||||
|
i = i + 1
|
||||||
|
|
||||||
|
|
||||||
|
# Memory debug specific
|
||||||
|
libxml2.cleanupParser()
|
||||||
|
if libxml2.debugMemory(1) == 0:
|
||||||
|
print "OK"
|
||||||
|
else:
|
||||||
|
print "Memory leak %d bytes" % (libxml2.debugMemory(1))
|
||||||
|
libxml2.dumpMemory()
|
||||||
|
|
@ -76,7 +76,7 @@ if str != """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
str = doc.serialize("ISO-8859-1")
|
str = doc.serialize("ISO-8859-1")
|
||||||
if str != """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
if str != """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||||
<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type"><title>Hello</title></head><body><p>hello</p></body></html>
|
<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Hello</title></head><body><p>hello</p></body></html>
|
||||||
""":
|
""":
|
||||||
print "error serializing HTML document 2"
|
print "error serializing HTML document 2"
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
@ -84,7 +84,7 @@ str = doc.serialize(format=1)
|
|||||||
if str != """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
if str != """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type">
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
<title>Hello</title>
|
<title>Hello</title>
|
||||||
</head>
|
</head>
|
||||||
<body><p>hello</p></body>
|
<body><p>hello</p></body>
|
||||||
@ -96,7 +96,7 @@ str = doc.serialize("iso-8859-1", 1)
|
|||||||
if str != """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
if str != """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta content="text/html; charset=iso-8859-1" http-equiv="Content-Type">
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
<title>Hello</title>
|
<title>Hello</title>
|
||||||
</head>
|
</head>
|
||||||
<body><p>hello</p></body>
|
<body><p>hello</p></body>
|
||||||
@ -115,13 +115,13 @@ if str != """<html><head><title>Hello</title></head><body><p>hello</p></body></h
|
|||||||
print "error serializing HTML root 1"
|
print "error serializing HTML root 1"
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
str = root.serialize("ISO-8859-1")
|
str = root.serialize("ISO-8859-1")
|
||||||
if str != """<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type"><title>Hello</title></head><body><p>hello</p></body></html>""":
|
if str != """<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Hello</title></head><body><p>hello</p></body></html>""":
|
||||||
print "error serializing HTML root 2"
|
print "error serializing HTML root 2"
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
str = root.serialize(format=1)
|
str = root.serialize(format=1)
|
||||||
if str != """<html>
|
if str != """<html>
|
||||||
<head>
|
<head>
|
||||||
<meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type">
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
<title>Hello</title>
|
<title>Hello</title>
|
||||||
</head>
|
</head>
|
||||||
<body><p>hello</p></body>
|
<body><p>hello</p></body>
|
||||||
@ -131,7 +131,7 @@ if str != """<html>
|
|||||||
str = root.serialize("iso-8859-1", 1)
|
str = root.serialize("iso-8859-1", 1)
|
||||||
if str != """<html>
|
if str != """<html>
|
||||||
<head>
|
<head>
|
||||||
<meta content="text/html; charset=iso-8859-1" http-equiv="Content-Type">
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
<title>Hello</title>
|
<title>Hello</title>
|
||||||
</head>
|
</head>
|
||||||
<body><p>hello</p></body>
|
<body><p>hello</p></body>
|
||||||
|
@ -469,3 +469,39 @@ libxml_xmlCatalogPtrWrap(xmlCatalogPtr catal)
|
|||||||
(char *) "xmlCatalogPtr", NULL);
|
(char *) "xmlCatalogPtr", NULL);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
libxml_xmlOutputBufferPtrWrap(xmlOutputBufferPtr buffer)
|
||||||
|
{
|
||||||
|
PyObject *ret;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("libxml_xmlOutputBufferPtrWrap: buffer = %p\n", buffer);
|
||||||
|
#endif
|
||||||
|
if (buffer == NULL) {
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return (Py_None);
|
||||||
|
}
|
||||||
|
ret =
|
||||||
|
PyCObject_FromVoidPtrAndDesc((void *) buffer,
|
||||||
|
(char *) "xmlOutputBufferPtr", NULL);
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
libxml_xmlParserInputBufferPtrWrap(xmlParserInputBufferPtr buffer)
|
||||||
|
{
|
||||||
|
PyObject *ret;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("libxml_xmlParserInputBufferPtrWrap: buffer = %p\n", buffer);
|
||||||
|
#endif
|
||||||
|
if (buffer == NULL) {
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return (Py_None);
|
||||||
|
}
|
||||||
|
ret =
|
||||||
|
PyCObject_FromVoidPtrAndDesc((void *) buffer,
|
||||||
|
(char *) "xmlParserInputBufferPtr", NULL);
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user