mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-04-20 12:27:48 +03:00
959 lines
23 KiB
C
959 lines
23 KiB
C
#include <Python.h>
|
|
|
|
#include <libxml/xmlmemory.h>
|
|
#include <libxml/parser.h>
|
|
#include <libxml/tree.h>
|
|
#include <libxml/xpath.h>
|
|
#include <libxml/xpathInternals.h>
|
|
#include "libxml_wrap.h"
|
|
#include "libxml2-py.h"
|
|
|
|
/* #define DEBUG */
|
|
/* #define DEBUG_XPATH */
|
|
|
|
/************************************************************************
|
|
* *
|
|
* Per type specific glue *
|
|
* *
|
|
************************************************************************/
|
|
PyObject *
|
|
libxml_intWrap(int val) {
|
|
PyObject *ret;
|
|
|
|
#ifdef DEBUG
|
|
printf("libxml_intWrap: val = %d\n", val);
|
|
#endif
|
|
ret = PyInt_FromLong((long) val);
|
|
return(ret);
|
|
}
|
|
|
|
PyObject *
|
|
libxml_doubleWrap(double val) {
|
|
PyObject *ret;
|
|
|
|
#ifdef DEBUG
|
|
printf("libxml_doubleWrap: val = %f\n", val);
|
|
#endif
|
|
ret = PyFloat_FromDouble((double) val);
|
|
return(ret);
|
|
}
|
|
|
|
PyObject *
|
|
libxml_charPtrWrap(char *str) {
|
|
PyObject *ret;
|
|
|
|
#ifdef DEBUG
|
|
printf("libxml_xmlcharPtrWrap: str = %s\n", str);
|
|
#endif
|
|
if (str == NULL) {
|
|
Py_INCREF(Py_None);
|
|
return(Py_None);
|
|
}
|
|
/* TODO: look at deallocation */
|
|
ret = PyString_FromString(str);
|
|
xmlFree(str);
|
|
return(ret);
|
|
}
|
|
|
|
PyObject *
|
|
libxml_xmlCharPtrWrap(xmlChar *str) {
|
|
PyObject *ret;
|
|
|
|
#ifdef DEBUG
|
|
printf("libxml_xmlCharPtrWrap: str = %s\n", str);
|
|
#endif
|
|
if (str == NULL) {
|
|
Py_INCREF(Py_None);
|
|
return(Py_None);
|
|
}
|
|
/* TODO: look at deallocation */
|
|
ret = PyString_FromString(str);
|
|
xmlFree(str);
|
|
return(ret);
|
|
}
|
|
|
|
PyObject *
|
|
libxml_constcharPtrWrap(const char *str) {
|
|
PyObject *ret;
|
|
|
|
#ifdef DEBUG
|
|
printf("libxml_xmlcharPtrWrap: str = %s\n", str);
|
|
#endif
|
|
if (str == NULL) {
|
|
Py_INCREF(Py_None);
|
|
return(Py_None);
|
|
}
|
|
/* TODO: look at deallocation */
|
|
ret = PyString_FromString(str);
|
|
return(ret);
|
|
}
|
|
|
|
PyObject *
|
|
libxml_constxmlCharPtrWrap(const xmlChar *str) {
|
|
PyObject *ret;
|
|
|
|
#ifdef DEBUG
|
|
printf("libxml_xmlCharPtrWrap: str = %s\n", str);
|
|
#endif
|
|
if (str == NULL) {
|
|
Py_INCREF(Py_None);
|
|
return(Py_None);
|
|
}
|
|
/* TODO: look at deallocation */
|
|
ret = PyString_FromString(str);
|
|
return(ret);
|
|
}
|
|
|
|
PyObject *
|
|
libxml_xmlDocPtrWrap(xmlDocPtr doc) {
|
|
PyObject *ret;
|
|
|
|
#ifdef DEBUG
|
|
printf("libxml_xmlDocPtrWrap: doc = %p\n", doc);
|
|
#endif
|
|
if (doc == NULL) {
|
|
Py_INCREF(Py_None);
|
|
return(Py_None);
|
|
}
|
|
/* TODO: look at deallocation */
|
|
ret = PyCObject_FromVoidPtrAndDesc((void *) doc, "xmlDocPtr", NULL);
|
|
return(ret);
|
|
}
|
|
|
|
PyObject *
|
|
libxml_xmlNodePtrWrap(xmlNodePtr node) {
|
|
PyObject *ret;
|
|
|
|
#ifdef DEBUG
|
|
printf("libxml_xmlNodePtrWrap: node = %p\n", node);
|
|
#endif
|
|
if (node == NULL) {
|
|
Py_INCREF(Py_None);
|
|
return(Py_None);
|
|
}
|
|
ret = PyCObject_FromVoidPtrAndDesc((void *) node, "xmlNodePtr", NULL);
|
|
return(ret);
|
|
}
|
|
|
|
PyObject *
|
|
libxml_xmlNsPtrWrap(xmlNsPtr ns) {
|
|
PyObject *ret;
|
|
|
|
#ifdef DEBUG
|
|
printf("libxml_xmlNsPtrWrap: node = %p\n", ns);
|
|
#endif
|
|
if (ns == NULL) {
|
|
Py_INCREF(Py_None);
|
|
return(Py_None);
|
|
}
|
|
ret = PyCObject_FromVoidPtrAndDesc((void *) ns, "xmlNsPtr", NULL);
|
|
return(ret);
|
|
}
|
|
|
|
PyObject *
|
|
libxml_xmlAttrPtrWrap(xmlAttrPtr attr) {
|
|
PyObject *ret;
|
|
|
|
#ifdef DEBUG
|
|
printf("libxml_xmlAttrNodePtrWrap: attr = %p\n", attr);
|
|
#endif
|
|
if (attr == NULL) {
|
|
Py_INCREF(Py_None);
|
|
return(Py_None);
|
|
}
|
|
ret = PyCObject_FromVoidPtrAndDesc((void *) attr, "xmlAttrPtr", NULL);
|
|
return(ret);
|
|
}
|
|
|
|
PyObject *
|
|
libxml_xmlAttributePtrWrap(xmlAttributePtr attr) {
|
|
PyObject *ret;
|
|
|
|
#ifdef DEBUG
|
|
printf("libxml_xmlAttributePtrWrap: attr = %p\n", attr);
|
|
#endif
|
|
if (attr == NULL) {
|
|
Py_INCREF(Py_None);
|
|
return(Py_None);
|
|
}
|
|
ret = PyCObject_FromVoidPtrAndDesc((void *) attr, "xmlAttributePtr", NULL);
|
|
return(ret);
|
|
}
|
|
|
|
PyObject *
|
|
libxml_xmlElementPtrWrap(xmlElementPtr elem) {
|
|
PyObject *ret;
|
|
|
|
#ifdef DEBUG
|
|
printf("libxml_xmlElementNodePtrWrap: elem = %p\n", elem);
|
|
#endif
|
|
if (elem == NULL) {
|
|
Py_INCREF(Py_None);
|
|
return(Py_None);
|
|
}
|
|
ret = PyCObject_FromVoidPtrAndDesc((void *) elem, "xmlElementPtr", NULL);
|
|
return(ret);
|
|
}
|
|
|
|
PyObject *
|
|
libxml_xmlXPathContextPtrWrap(xmlXPathContextPtr ctxt) {
|
|
PyObject *ret;
|
|
|
|
#ifdef DEBUG
|
|
printf("libxml_xmlXPathContextPtrWrap: ctxt = %p\n", ctxt);
|
|
#endif
|
|
if (ctxt == NULL) {
|
|
Py_INCREF(Py_None);
|
|
return(Py_None);
|
|
}
|
|
ret = PyCObject_FromVoidPtrAndDesc((void *) ctxt, "xmlXPathContextPtr",
|
|
NULL);
|
|
return(ret);
|
|
}
|
|
|
|
PyObject *
|
|
libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj) {
|
|
PyObject *ret;
|
|
|
|
#ifdef DEBUG
|
|
printf("libxml_xmlXPathObjectPtrWrap: ctxt = %p\n", obj);
|
|
#endif
|
|
if (obj == NULL) {
|
|
Py_INCREF(Py_None);
|
|
return(Py_None);
|
|
}
|
|
switch(obj->type) {
|
|
case XPATH_XSLT_TREE:
|
|
/* TODO !!!! Allocation problems */
|
|
case XPATH_NODESET:
|
|
if ((obj->nodesetval == NULL) || (obj->nodesetval->nodeNr == 0))
|
|
ret = PyList_New(0);
|
|
else {
|
|
int i;
|
|
xmlNodePtr node;
|
|
|
|
ret = PyList_New(obj->nodesetval->nodeNr);
|
|
for (i = 0;i < obj->nodesetval->nodeNr;i++) {
|
|
node = obj->nodesetval->nodeTab[i];
|
|
/* TODO: try to cast directly to the proper node type */
|
|
PyList_SetItem(ret, i, libxml_xmlNodePtrWrap(node));
|
|
}
|
|
}
|
|
break;
|
|
case XPATH_BOOLEAN:
|
|
ret = PyInt_FromLong((long) obj->boolval);
|
|
break;
|
|
case XPATH_NUMBER:
|
|
ret = PyFloat_FromDouble(obj->floatval);
|
|
break;
|
|
case XPATH_STRING:
|
|
ret = PyString_FromString(obj->stringval);
|
|
break;
|
|
case XPATH_POINT:
|
|
case XPATH_RANGE:
|
|
case XPATH_LOCATIONSET:
|
|
default:
|
|
printf("Unable to convert XPath object type %d\n", obj->type);
|
|
Py_INCREF(Py_None);
|
|
ret = Py_None;
|
|
}
|
|
xmlXPathFreeObject(obj);
|
|
return(ret);
|
|
}
|
|
|
|
xmlXPathObjectPtr
|
|
libxml_xmlXPathObjectPtrConvert(PyObject * obj) {
|
|
xmlXPathObjectPtr ret;
|
|
|
|
#ifdef DEBUG
|
|
printf("libxml_xmlXPathObjectPtrConvert: obj = %p\n", obj);
|
|
#endif
|
|
if (obj == NULL) {
|
|
return(NULL);
|
|
}
|
|
if PyFloat_Check(obj) {
|
|
ret = xmlXPathNewFloat((double) PyFloat_AS_DOUBLE(obj));
|
|
} else if PyString_Check(obj) {
|
|
xmlChar *str;
|
|
|
|
str = xmlStrndup((const xmlChar *)PyString_AS_STRING(obj),
|
|
PyString_GET_SIZE(obj));
|
|
ret = xmlXPathWrapString(str);
|
|
} else {
|
|
printf("Unable to convert Python Object to XPath");
|
|
}
|
|
Py_DECREF(obj);
|
|
return(ret);
|
|
}
|
|
/************************************************************************
|
|
* *
|
|
* XPath extensions *
|
|
* *
|
|
************************************************************************/
|
|
|
|
static int libxml_xpathCallbacksInitialized = 0;
|
|
|
|
typedef struct libxml_xpathCallback {
|
|
xmlXPathContextPtr ctx;
|
|
xmlChar *name;
|
|
xmlChar *ns_uri;
|
|
PyObject *function;
|
|
} libxml_xpathCallback, *libxml_xpathCallbackPtr;
|
|
static libxml_xpathCallback libxml_xpathCallbacks[10];
|
|
static int libxml_xpathCallbacksNb = 0;
|
|
static int libxml_xpathCallbacksMax = 10;
|
|
|
|
/* TODO: this is not reentrant !!! MUST FIX with a per context hash */
|
|
static PyObject *current_function = NULL;
|
|
|
|
static void
|
|
libxml_xmlXPathFuncCallback(xmlXPathParserContextPtr ctxt, int nargs) {
|
|
PyObject *list, *cur, *result;
|
|
xmlXPathObjectPtr obj;
|
|
int i;
|
|
|
|
#ifdef DEBUG_XPATH
|
|
printf("libxml_xmlXPathFuncCallback called\n");
|
|
#endif
|
|
|
|
list = PyTuple_New(nargs);
|
|
for (i = 0;i < nargs;i++) {
|
|
obj = valuePop(ctxt);
|
|
cur = libxml_xmlXPathObjectPtrWrap(obj);
|
|
PyTuple_SetItem(list, i, cur);
|
|
}
|
|
result = PyEval_CallObject(current_function, list);
|
|
Py_DECREF(list);
|
|
|
|
obj = libxml_xmlXPathObjectPtrConvert(result);
|
|
valuePush(ctxt, obj);
|
|
}
|
|
|
|
static xmlXPathFunction
|
|
libxml_xmlXPathFuncLookupFunc(void *ctxt, const xmlChar *name,
|
|
const xmlChar *ns_uri) {
|
|
int i;
|
|
#ifdef DEBUG_XPATH
|
|
printf("libxml_xmlXPathFuncLookupFunc(%p, %s, %s) called\n",
|
|
ctxt, name, ns_uri);
|
|
#endif
|
|
for (i = 0;i < libxml_xpathCallbacksNb;i++) {
|
|
if ((ctxt == libxml_xpathCallbacks[i].ctx) &&
|
|
(xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
|
|
(xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
|
|
current_function = libxml_xpathCallbacks[i].function;
|
|
return(libxml_xmlXPathFuncCallback);
|
|
}
|
|
}
|
|
current_function = NULL;
|
|
return(NULL);
|
|
}
|
|
|
|
static void
|
|
libxml_xpathCallbacksInitialize(void) {
|
|
int i;
|
|
|
|
if (libxml_xpathCallbacksInitialized != 0)
|
|
return;
|
|
|
|
#ifdef DEBUG_XPATH
|
|
printf("libxml_xpathCallbacksInitialized called\n");
|
|
#endif
|
|
|
|
for (i = 0;i < 10;i++) {
|
|
libxml_xpathCallbacks[i].ctx = NULL;
|
|
libxml_xpathCallbacks[i].name = NULL;
|
|
libxml_xpathCallbacks[i].ns_uri = NULL;
|
|
libxml_xpathCallbacks[i].function = NULL;
|
|
}
|
|
current_function = NULL;
|
|
libxml_xpathCallbacksInitialized = 1;
|
|
}
|
|
|
|
PyObject *
|
|
libxml_xmlRegisterXPathFunction(PyObject *self, PyObject *args) {
|
|
PyObject *py_retval;
|
|
int c_retval = 0;
|
|
xmlChar *name;
|
|
xmlChar *ns_uri;
|
|
xmlXPathContextPtr ctx;
|
|
PyObject *pyobj_ctx;
|
|
PyObject *pyobj_f;
|
|
int i;
|
|
|
|
if (!PyArg_ParseTuple(args, "OszO:registerXPathFunction", &pyobj_ctx,
|
|
&name, &ns_uri, &pyobj_f))
|
|
return(NULL);
|
|
|
|
ctx = (xmlXPathContextPtr) PyxmlXPathContext_Get(pyobj_ctx);
|
|
if (libxml_xpathCallbacksInitialized == 0)
|
|
libxml_xpathCallbacksInitialize();
|
|
xmlXPathRegisterFuncLookup(ctx, libxml_xmlXPathFuncLookupFunc, ctx);
|
|
|
|
if ((pyobj_ctx == NULL) || (name == NULL) || (pyobj_f == NULL)) {
|
|
py_retval = libxml_intWrap(-1);
|
|
return(py_retval);
|
|
}
|
|
|
|
#ifdef DEBUG_XPATH
|
|
printf("libxml_registerXPathFunction(%p, %s, %s) called\n",
|
|
ctx, name, ns_uri);
|
|
#endif
|
|
for (i = 0;i < libxml_xpathCallbacksNb;i++) {
|
|
if ((ctx == libxml_xpathCallbacks[i].ctx) &&
|
|
(xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
|
|
(xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
|
|
Py_XINCREF(pyobj_f);
|
|
Py_XDECREF(libxml_xpathCallbacks[i].function);
|
|
libxml_xpathCallbacks[i].function = pyobj_f;
|
|
c_retval = 1;
|
|
goto done;
|
|
}
|
|
}
|
|
if (libxml_xpathCallbacksNb >= libxml_xpathCallbacksMax) {
|
|
printf("libxml_registerXPathFunction() table full\n");
|
|
} else {
|
|
i = libxml_xpathCallbacksNb++;
|
|
Py_XINCREF(pyobj_f);
|
|
libxml_xpathCallbacks[i].ctx = ctx;
|
|
libxml_xpathCallbacks[i].name = xmlStrdup(name);
|
|
libxml_xpathCallbacks[i].ns_uri = xmlStrdup(ns_uri);
|
|
libxml_xpathCallbacks[i].function = pyobj_f;
|
|
c_retval = 1;
|
|
}
|
|
done:
|
|
py_retval = libxml_intWrap((int) c_retval);
|
|
return(py_retval);
|
|
}
|
|
|
|
/************************************************************************
|
|
* *
|
|
* The PyxmlNode type *
|
|
* *
|
|
************************************************************************/
|
|
static void
|
|
PyxmlNode_dealloc(PyxmlNode_Object * self)
|
|
{
|
|
printf("TODO PyxmlNode_dealloc\n");
|
|
PyMem_DEL(self);
|
|
}
|
|
|
|
static int
|
|
PyxmlNode_compare(PyxmlNode_Object * self, PyxmlNode_Object * v)
|
|
{
|
|
if (self->obj == v->obj)
|
|
return 0;
|
|
if (self->obj > v->obj)
|
|
return -1;
|
|
return 1;
|
|
}
|
|
|
|
static long
|
|
PyxmlNode_hash(PyxmlNode_Object * self)
|
|
{
|
|
return (long) self->obj;
|
|
}
|
|
|
|
static PyObject *
|
|
PyxmlNode_repr(PyxmlNode_Object * self)
|
|
{
|
|
char buf[100];
|
|
|
|
sprintf(buf, "<xmlNode of type %d at %lx>",
|
|
PyxmlNode_Get(self)->type,
|
|
(long) PyxmlNode_Get(self));
|
|
return PyString_FromString(buf);
|
|
}
|
|
|
|
static char PyxmlNode_Type__doc__[] = "This is the type of libxml Nodes";
|
|
|
|
static PyTypeObject PyxmlNode_Type = {
|
|
PyObject_HEAD_INIT(&PyType_Type)
|
|
0, /*ob_size */
|
|
"xmlNode", /*tp_name */
|
|
sizeof(PyxmlNode_Object), /*tp_basicsize */
|
|
0, /*tp_itemsize */
|
|
(destructor) PyxmlNode_dealloc,/*tp_dealloc */
|
|
(printfunc) 0, /*tp_print */
|
|
(getattrfunc) 0, /*tp_getattr */
|
|
(setattrfunc) 0, /*tp_setattr */
|
|
(cmpfunc) PyxmlNode_compare,/*tp_compare */
|
|
(reprfunc) PyxmlNode_repr, /*tp_repr */
|
|
0, /*tp_as_number */
|
|
0, /*tp_as_sequence */
|
|
0, /*tp_as_mapping */
|
|
(hashfunc) PyxmlNode_hash, /*tp_hash */
|
|
(ternaryfunc) 0, /*tp_call */
|
|
(reprfunc) 0, /*tp_str */
|
|
0L, 0L, 0L, 0L,
|
|
PyxmlNode_Type__doc__
|
|
};
|
|
|
|
/************************************************************************
|
|
* *
|
|
* The PyxmlXPathContext type *
|
|
* *
|
|
************************************************************************/
|
|
static void
|
|
PyxmlXPathContext_dealloc(PyxmlXPathContext_Object * self)
|
|
{
|
|
printf("TODO PyxmlXPathContext_dealloc\n");
|
|
PyMem_DEL(self);
|
|
}
|
|
|
|
static int
|
|
PyxmlXPathContext_compare(PyxmlXPathContext_Object * self, PyxmlXPathContext_Object * v)
|
|
{
|
|
if (self->obj == v->obj)
|
|
return 0;
|
|
if (self->obj > v->obj)
|
|
return -1;
|
|
return 1;
|
|
}
|
|
|
|
static long
|
|
PyxmlXPathContext_hash(PyxmlXPathContext_Object * self)
|
|
{
|
|
return (long) self->obj;
|
|
}
|
|
|
|
static PyObject *
|
|
PyxmlXPathContext_repr(PyxmlXPathContext_Object * self)
|
|
{
|
|
char buf[100];
|
|
|
|
sprintf(buf, "<xmlXPathContext at %lx>",
|
|
(long) PyxmlXPathContext_Get(self));
|
|
return PyString_FromString(buf);
|
|
}
|
|
|
|
static char PyxmlXPathContext_Type__doc__[] = "This is the type of XPath evaluation contexts";
|
|
|
|
PyTypeObject PyxmlXPathContext_Type = {
|
|
PyObject_HEAD_INIT(&PyType_Type)
|
|
0, /*ob_size */
|
|
"xmlXPathContext", /*tp_name */
|
|
sizeof(PyxmlXPathContext_Object), /*tp_basicsize */
|
|
0, /*tp_itemsize */
|
|
(destructor) PyxmlXPathContext_dealloc,/*tp_dealloc */
|
|
(printfunc) 0, /*tp_print */
|
|
(getattrfunc) 0, /*tp_getattr */
|
|
(setattrfunc) 0, /*tp_setattr */
|
|
(cmpfunc) PyxmlXPathContext_compare,/*tp_compare */
|
|
(reprfunc) PyxmlXPathContext_repr, /*tp_repr */
|
|
0, /*tp_as_number */
|
|
0, /*tp_as_sequence */
|
|
0, /*tp_as_mapping */
|
|
(hashfunc) PyxmlXPathContext_hash, /*tp_hash */
|
|
(ternaryfunc) 0, /*tp_call */
|
|
(reprfunc) 0, /*tp_str */
|
|
0L, 0L, 0L, 0L,
|
|
PyxmlXPathContext_Type__doc__
|
|
};
|
|
|
|
/************************************************************************
|
|
* *
|
|
* Global properties access *
|
|
* *
|
|
************************************************************************/
|
|
static PyObject *
|
|
libxml_name(PyObject *self, PyObject *args)
|
|
{
|
|
PyObject *resultobj, *obj;
|
|
xmlNodePtr cur;
|
|
const xmlChar *res;
|
|
|
|
if (!PyArg_ParseTuple(args, "O:name", &obj))
|
|
return NULL;
|
|
cur = PyxmlNode_Get(obj);
|
|
|
|
#ifdef DEBUG
|
|
printf("libxml_name: cur = %p type %d\n", cur, cur->type);
|
|
#endif
|
|
|
|
switch(cur->type) {
|
|
case XML_DOCUMENT_NODE:
|
|
#ifdef LIBXML_DOCB_ENABLED
|
|
case XML_DOCB_DOCUMENT_NODE:
|
|
#endif
|
|
case XML_HTML_DOCUMENT_NODE: {
|
|
xmlDocPtr doc = (xmlDocPtr) cur;
|
|
res = doc->URL;
|
|
break;
|
|
}
|
|
case XML_ATTRIBUTE_NODE: {
|
|
xmlAttrPtr attr = (xmlAttrPtr) cur;
|
|
res = attr->name;
|
|
break;
|
|
}
|
|
case XML_NAMESPACE_DECL: {
|
|
xmlNsPtr ns = (xmlNsPtr) cur;
|
|
res = ns->prefix;
|
|
break;
|
|
}
|
|
default:
|
|
res = cur->name;
|
|
break;
|
|
}
|
|
resultobj = libxml_constxmlCharPtrWrap(res);
|
|
|
|
return resultobj;
|
|
}
|
|
|
|
static PyObject *
|
|
libxml_doc(PyObject *self, PyObject *args)
|
|
{
|
|
PyObject *resultobj, *obj;
|
|
xmlNodePtr cur;
|
|
xmlDocPtr res;
|
|
|
|
if (!PyArg_ParseTuple(args, "O:doc", &obj))
|
|
return NULL;
|
|
cur = PyxmlNode_Get(obj);
|
|
|
|
#ifdef DEBUG
|
|
printf("libxml_doc: cur = %p\n", cur);
|
|
#endif
|
|
|
|
switch(cur->type) {
|
|
case XML_DOCUMENT_NODE:
|
|
#ifdef LIBXML_DOCB_ENABLED
|
|
case XML_DOCB_DOCUMENT_NODE:
|
|
#endif
|
|
case XML_HTML_DOCUMENT_NODE:
|
|
res = NULL;
|
|
break;
|
|
case XML_ATTRIBUTE_NODE: {
|
|
xmlAttrPtr attr = (xmlAttrPtr) cur;
|
|
res = attr->doc;
|
|
break;
|
|
}
|
|
case XML_NAMESPACE_DECL:
|
|
res = NULL;
|
|
break;
|
|
default:
|
|
res = cur->doc;
|
|
break;
|
|
}
|
|
resultobj = libxml_xmlDocPtrWrap(res);
|
|
return resultobj;
|
|
}
|
|
|
|
static PyObject *
|
|
libxml_properties(PyObject *self, PyObject *args)
|
|
{
|
|
PyObject *resultobj, *obj;
|
|
xmlNodePtr cur = NULL;
|
|
xmlAttrPtr res;
|
|
|
|
if (!PyArg_ParseTuple(args, "O:properties", &obj))
|
|
return NULL;
|
|
cur = PyxmlNode_Get(obj);
|
|
if (cur->type == XML_ELEMENT_NODE)
|
|
res = cur->properties;
|
|
else
|
|
res = NULL;
|
|
resultobj = libxml_xmlAttrPtrWrap(res);
|
|
return resultobj;
|
|
}
|
|
|
|
static PyObject *
|
|
libxml_next(PyObject *self, PyObject *args)
|
|
{
|
|
PyObject *resultobj, *obj;
|
|
xmlNodePtr cur;
|
|
xmlNodePtr res;
|
|
|
|
if (!PyArg_ParseTuple(args, "O:next", &obj))
|
|
return NULL;
|
|
cur = PyxmlNode_Get(obj);
|
|
|
|
#ifdef DEBUG
|
|
printf("libxml_next: cur = %p\n", cur);
|
|
#endif
|
|
|
|
switch(cur->type) {
|
|
case XML_DOCUMENT_NODE:
|
|
#ifdef LIBXML_DOCB_ENABLED
|
|
case XML_DOCB_DOCUMENT_NODE:
|
|
#endif
|
|
case XML_HTML_DOCUMENT_NODE:
|
|
res = NULL;
|
|
break;
|
|
case XML_ATTRIBUTE_NODE: {
|
|
xmlAttrPtr attr = (xmlAttrPtr) cur;
|
|
res = (xmlNodePtr) attr->next;
|
|
break;
|
|
}
|
|
case XML_NAMESPACE_DECL: {
|
|
xmlNsPtr ns = (xmlNsPtr) cur;
|
|
res = (xmlNodePtr) ns->next;
|
|
break;
|
|
}
|
|
default:
|
|
res = cur->next;
|
|
break;
|
|
|
|
}
|
|
resultobj = libxml_xmlNodePtrWrap(res);
|
|
return resultobj;
|
|
}
|
|
|
|
static PyObject *
|
|
libxml_prev(PyObject *self, PyObject *args)
|
|
{
|
|
PyObject *resultobj, *obj;
|
|
xmlNodePtr cur;
|
|
xmlNodePtr res;
|
|
|
|
if (!PyArg_ParseTuple(args, "O:prev", &obj))
|
|
return NULL;
|
|
cur = PyxmlNode_Get(obj);
|
|
|
|
#ifdef DEBUG
|
|
printf("libxml_prev: cur = %p\n", cur);
|
|
#endif
|
|
|
|
switch(cur->type) {
|
|
case XML_DOCUMENT_NODE:
|
|
#ifdef LIBXML_DOCB_ENABLED
|
|
case XML_DOCB_DOCUMENT_NODE:
|
|
#endif
|
|
case XML_HTML_DOCUMENT_NODE:
|
|
res = NULL;
|
|
break;
|
|
case XML_ATTRIBUTE_NODE: {
|
|
xmlAttrPtr attr = (xmlAttrPtr) cur;
|
|
res = (xmlNodePtr) attr->next;
|
|
}
|
|
case XML_NAMESPACE_DECL:
|
|
res = NULL;
|
|
break;
|
|
default:
|
|
res = cur->next;
|
|
break;
|
|
}
|
|
resultobj = libxml_xmlNodePtrWrap(res);
|
|
return resultobj;
|
|
}
|
|
|
|
static PyObject *
|
|
libxml_children(PyObject *self, PyObject *args)
|
|
{
|
|
PyObject *resultobj, *obj;
|
|
xmlNodePtr cur;
|
|
xmlNodePtr res;
|
|
|
|
if (!PyArg_ParseTuple(args, "O:children", &obj))
|
|
return NULL;
|
|
cur = PyxmlNode_Get(obj);
|
|
|
|
#ifdef DEBUG
|
|
printf("libxml_children: cur = %p\n", cur);
|
|
#endif
|
|
|
|
switch(cur->type) {
|
|
case XML_ELEMENT_NODE:
|
|
case XML_ENTITY_REF_NODE:
|
|
case XML_ENTITY_NODE:
|
|
case XML_PI_NODE:
|
|
case XML_COMMENT_NODE:
|
|
case XML_DOCUMENT_NODE:
|
|
#ifdef LIBXML_DOCB_ENABLED
|
|
case XML_DOCB_DOCUMENT_NODE:
|
|
#endif
|
|
case XML_HTML_DOCUMENT_NODE:
|
|
case XML_DTD_NODE:
|
|
res = cur->children;
|
|
break;
|
|
case XML_ATTRIBUTE_NODE: {
|
|
xmlAttrPtr attr = (xmlAttrPtr) cur;
|
|
res = attr->children;
|
|
break;
|
|
}
|
|
default:
|
|
res = NULL;
|
|
break;
|
|
}
|
|
resultobj = libxml_xmlNodePtrWrap(res);
|
|
return resultobj;
|
|
}
|
|
|
|
static PyObject *
|
|
libxml_last(PyObject *self, PyObject *args)
|
|
{
|
|
PyObject *resultobj, *obj;
|
|
xmlNodePtr cur;
|
|
xmlNodePtr res;
|
|
|
|
if (!PyArg_ParseTuple(args, "O:last", &obj))
|
|
return NULL;
|
|
cur = PyxmlNode_Get(obj);
|
|
|
|
#ifdef DEBUG
|
|
printf("libxml_last: cur = %p\n", cur);
|
|
#endif
|
|
|
|
switch(cur->type) {
|
|
case XML_ELEMENT_NODE:
|
|
case XML_ENTITY_REF_NODE:
|
|
case XML_ENTITY_NODE:
|
|
case XML_PI_NODE:
|
|
case XML_COMMENT_NODE:
|
|
case XML_DOCUMENT_NODE:
|
|
#ifdef LIBXML_DOCB_ENABLED
|
|
case XML_DOCB_DOCUMENT_NODE:
|
|
#endif
|
|
case XML_HTML_DOCUMENT_NODE:
|
|
case XML_DTD_NODE:
|
|
res = cur->last;
|
|
break;
|
|
case XML_ATTRIBUTE_NODE: {
|
|
xmlAttrPtr attr = (xmlAttrPtr) cur;
|
|
res = attr->last;
|
|
}
|
|
default:
|
|
res = NULL;
|
|
break;
|
|
}
|
|
resultobj = libxml_xmlNodePtrWrap(res);
|
|
return resultobj;
|
|
}
|
|
|
|
static PyObject *
|
|
libxml_parent(PyObject *self, PyObject *args)
|
|
{
|
|
PyObject *resultobj, *obj;
|
|
xmlNodePtr cur;
|
|
xmlNodePtr res;
|
|
|
|
if (!PyArg_ParseTuple(args, "O:parent", &obj))
|
|
return NULL;
|
|
cur = PyxmlNode_Get(obj);
|
|
|
|
#ifdef DEBUG
|
|
printf("libxml_parent: cur = %p\n", cur);
|
|
#endif
|
|
|
|
switch(cur->type) {
|
|
case XML_DOCUMENT_NODE:
|
|
case XML_HTML_DOCUMENT_NODE:
|
|
#ifdef LIBXML_DOCB_ENABLED
|
|
case XML_DOCB_DOCUMENT_NODE:
|
|
#endif
|
|
res = NULL;
|
|
break;
|
|
case XML_ATTRIBUTE_NODE: {
|
|
xmlAttrPtr attr = (xmlAttrPtr) cur;
|
|
res = attr->parent;
|
|
}
|
|
case XML_ENTITY_DECL:
|
|
case XML_NAMESPACE_DECL:
|
|
case XML_XINCLUDE_START:
|
|
case XML_XINCLUDE_END:
|
|
res = NULL;
|
|
break;
|
|
default:
|
|
res = cur->parent;
|
|
break;
|
|
}
|
|
resultobj = libxml_xmlNodePtrWrap(res);
|
|
return resultobj;
|
|
}
|
|
|
|
static PyObject *
|
|
libxml_type(PyObject *self, PyObject *args)
|
|
{
|
|
PyObject *resultobj, *obj;
|
|
xmlNodePtr cur;
|
|
const xmlChar *res;
|
|
|
|
if (!PyArg_ParseTuple(args, "O:last", &obj))
|
|
return NULL;
|
|
cur = PyxmlNode_Get(obj);
|
|
|
|
#ifdef DEBUG
|
|
printf("libxml_type: cur = %p\n", cur);
|
|
#endif
|
|
|
|
switch(cur->type) {
|
|
case XML_ELEMENT_NODE:
|
|
res = (const xmlChar *) "element"; break;
|
|
case XML_ATTRIBUTE_NODE:
|
|
res = (const xmlChar *) "attribute"; break;
|
|
case XML_TEXT_NODE:
|
|
res = (const xmlChar *) "text"; break;
|
|
case XML_CDATA_SECTION_NODE:
|
|
res = (const xmlChar *) "cdata"; break;
|
|
case XML_ENTITY_REF_NODE:
|
|
res = (const xmlChar *) "entity_ref"; break;
|
|
case XML_ENTITY_NODE:
|
|
res = (const xmlChar *) "entity"; break;
|
|
case XML_PI_NODE:
|
|
res = (const xmlChar *) "pi"; break;
|
|
case XML_COMMENT_NODE:
|
|
res = (const xmlChar *) "comment"; break;
|
|
case XML_DOCUMENT_NODE:
|
|
res = (const xmlChar *) "document_xml"; break;
|
|
case XML_DOCUMENT_TYPE_NODE:
|
|
res = (const xmlChar *) "doctype"; break;
|
|
case XML_DOCUMENT_FRAG_NODE:
|
|
res = (const xmlChar *) "fragment"; break;
|
|
case XML_NOTATION_NODE:
|
|
res = (const xmlChar *) "notation"; break;
|
|
case XML_HTML_DOCUMENT_NODE:
|
|
res = (const xmlChar *) "document_html"; break;
|
|
case XML_DTD_NODE:
|
|
res = (const xmlChar *) "dtd"; break;
|
|
case XML_ELEMENT_DECL:
|
|
res = (const xmlChar *) "elem_decl"; break;
|
|
case XML_ATTRIBUTE_DECL:
|
|
res = (const xmlChar *) "attribute_decl"; break;
|
|
case XML_ENTITY_DECL:
|
|
res = (const xmlChar *) "entity_decl"; break;
|
|
case XML_NAMESPACE_DECL:
|
|
res = (const xmlChar *) "namespace"; break;
|
|
case XML_XINCLUDE_START:
|
|
res = (const xmlChar *) "xinclude_start"; break;
|
|
case XML_XINCLUDE_END:
|
|
res = (const xmlChar *) "xinclude_end"; break;
|
|
#ifdef LIBXML_DOCB_ENABLED
|
|
case XML_DOCB_DOCUMENT_NODE:
|
|
res = (const xmlChar *) "document_docbook"; break;
|
|
#endif
|
|
}
|
|
#ifdef DEBUG
|
|
printf("libxml_type: cur = %p: %s\n", cur, res);
|
|
#endif
|
|
|
|
resultobj = libxml_constxmlCharPtrWrap(res);
|
|
return resultobj;
|
|
}
|
|
|
|
/************************************************************************
|
|
* *
|
|
* The registration stuff *
|
|
* *
|
|
************************************************************************/
|
|
static PyMethodDef libxmlMethods[] = {
|
|
#include "libxml2-export.c"
|
|
{ "name", libxml_name, METH_VARARGS },
|
|
{ "children", libxml_children, METH_VARARGS },
|
|
{ "properties", libxml_properties, METH_VARARGS },
|
|
{ "last", libxml_last, METH_VARARGS },
|
|
{ "prev", libxml_prev, METH_VARARGS },
|
|
{ "next", libxml_next, METH_VARARGS },
|
|
{ "parent", libxml_parent, METH_VARARGS },
|
|
{ "type", libxml_type, METH_VARARGS },
|
|
{ "doc", libxml_doc, METH_VARARGS },
|
|
};
|
|
|
|
void init_libxml(void) {
|
|
PyObject *m, *d;
|
|
m = Py_InitModule("_libxml", libxmlMethods);
|
|
d = PyModule_GetDict(m);
|
|
PyDict_SetItemString(d, "xmlNodeType", (PyObject *)&PyxmlNode_Type);
|
|
PyDict_SetItemString(d, "xmlXPathContextType", (PyObject *)&PyxmlXPathContext_Type);
|
|
}
|
|
|