commited early version of a python binding for private use only ATM Daniel
* python/generator.py python/libxml.c python/libxml.py
python/libxml_wrap.h: commited early version of a python binding
for private use only ATM
Daniel
diff --git a/python/generator.py b/python/generator.py
new file mode 100755
index 0000000..2942854
--- /dev/null
+++ b/python/generator.py
@@ -0,0 +1,284 @@
+#!/usr/bin/python -u
+#
+# generate python wrappers from the XML API description
+#
+
+functions = {}
+
+import os
+import xmllib
+try:
+ import sgmlop
+except ImportError:
+ sgmlop = None # accelerator not available
+
+debug = 0
+
+if sgmlop:
+ class FastParser:
+ """sgmlop based XML parser. this is typically 15x faster
+ than SlowParser..."""
+
+ def __init__(self, target):
+
+ # setup callbacks
+ self.finish_starttag = target.start
+ self.finish_endtag = target.end
+ self.handle_data = target.data
+
+ # activate parser
+ self.parser = sgmlop.XMLParser()
+ self.parser.register(self)
+ self.feed = self.parser.feed
+ self.entity = {
+ "amp": "&", "gt": ">", "lt": "<",
+ "apos": "'", "quot": '"'
+ }
+
+ def close(self):
+ try:
+ self.parser.close()
+ finally:
+ self.parser = self.feed = None # nuke circular reference
+
+ def handle_entityref(self, entity):
+ # <string> entity
+ try:
+ self.handle_data(self.entity[entity])
+ except KeyError:
+ self.handle_data("&%s;" % entity)
+
+else:
+ FastParser = None
+
+
+class SlowParser(xmllib.XMLParser):
+ """slow but safe standard parser, based on the XML parser in
+ Python's standard library."""
+
+ def __init__(self, target):
+ self.unknown_starttag = target.start
+ self.handle_data = target.data
+ self.unknown_endtag = target.end
+ xmllib.XMLParser.__init__(self)
+
+def getparser(target = None):
+ # get the fastest available parser, and attach it to an
+ # unmarshalling object. return both objects.
+ if target == None:
+ target = docParser()
+ if FastParser:
+ return FastParser(target), target
+ return SlowParser(target), target
+
+class docParser:
+ def __init__(self):
+ self._methodname = None
+ self._data = []
+ self.in_function = 0
+
+ def close(self):
+ if debug:
+ print "close"
+
+ def getmethodname(self):
+ return self._methodname
+
+ def data(self, text):
+ if debug:
+ print "data %s" % text
+ self._data.append(text)
+
+ def start(self, tag, attrs):
+ if debug:
+ print "start %s, %s" % (tag, attrs)
+ if tag == 'function':
+ self._data = []
+ self.in_function = 1
+ self.function = None
+ self.function_args = []
+ self.function_descr = None
+ self.function_return = None
+ self.function_file = None
+ if attrs.has_key('name'):
+ self.function = attrs['name']
+ if attrs.has_key('file'):
+ self.function_file = attrs['file']
+ elif tag == 'info':
+ self._data = []
+ elif tag == 'arg':
+ if self.in_function == 1:
+ self.function_arg_name = None
+ self.function_arg_type = None
+ self.function_arg_info = None
+ if attrs.has_key('name'):
+ self.function_arg_name = attrs['name']
+ if attrs.has_key('type'):
+ self.function_arg_type = attrs['type']
+ if attrs.has_key('info'):
+ self.function_arg_info = attrs['info']
+ elif tag == 'return':
+ if self.in_function == 1:
+ self.function_return_type = None
+ self.function_return_info = None
+ if attrs.has_key('type'):
+ self.function_return_type = attrs['type']
+ if attrs.has_key('info'):
+ self.function_return_info = attrs['info']
+
+
+ def end(self, tag):
+ if debug:
+ print "end %s" % tag
+ if tag == 'function':
+ if self.function != None:
+ function(self.function, self.function_descr,
+ self.function_return, self.function_args,
+ self.function_file)
+ self.in_function = 0
+ elif tag == 'arg':
+ if self.in_function == 1:
+ self.function_args.append([self.function_arg_name,
+ self.function_arg_type,
+ self.function_arg_info])
+ elif tag == 'return':
+ if self.in_function == 1:
+ self.function_return = [self.function_return_type,
+ self.function_return_info]
+ elif tag == 'info':
+ str = ''
+ for c in self._data:
+ str = str + c
+ if self.in_function == 1:
+ self.function_descr = str
+
+
+def function(name, desc, ret, args, file):
+ global functions
+
+ functions[name] = (desc, ret, args, file)
+
+skipped_modules = {
+ 'xmlmemory': None,
+}
+py_types = {
+ 'void': (None, None, None),
+ 'int': ('i', None, "int"),
+ 'xmlChar': ('c', None, "int"),
+ 'char *': ('s', None, "charPtr"),
+ 'const char *': ('s', None, "charPtr"),
+ 'xmlChar *': ('s', None, "xmlCharPtr"),
+ 'const xmlChar *': ('s', None, "xmlCharPtr"),
+}
+
+unknown_types = {}
+
+def print_function_wrapper(name, output):
+ global py_types
+ global unknown_types
+ global functions
+ global skipped_modules
+
+ try:
+ (desc, ret, args, file) = functions[name]
+ except:
+ print "failed to get function %s infos"
+ return
+
+ if skipped_modules.has_key(file):
+ return 0
+
+ c_call = "";
+ format=""
+ format_args=""
+ c_args=""
+ c_return=""
+ for arg in args:
+ c_args = c_args + " %s %s;\n" % (arg[1], arg[0])
+ if py_types.has_key(arg[1]):
+ (f, t, n) = py_types[arg[1]]
+ if f != None:
+ format = format + f
+ if t != None:
+ format_args = format_args + ", &%s" % (t)
+ format_args = format_args + ", &%s" % (arg[0])
+ if c_call != "":
+ c_call = c_call + ", ";
+ c_call = c_call + "%s" % (arg[0])
+ else:
+ if unknown_types.has_key(arg[1]):
+ lst = unknown_types[arg[1]]
+ lst.append(name)
+ else:
+ unknown_types[arg[1]] = [name]
+ return -1
+ if format != "":
+ format = format + ":%s" % (name)
+
+ if ret[0] == 'void':
+ c_call = "\n %s(%s);\n" % (name, c_call);
+ ret_convert = " Py_INCREF(Py_None);\n return(Py_None);\n"
+ elif py_types.has_key(ret[0]):
+ (f, t, n) = py_types[ret[0]]
+ c_return = " %s c_retval;\n" % (ret[0])
+ c_call = "\n c_retval = %s(%s);\n" % (name, c_call);
+ ret_convert = " py_retval = libxml_%sWrap(c_retval);\n return(py_retval);\n" % (n)
+ else:
+ if unknown_types.has_key(ret[0]):
+ lst = unknown_types[ret[0]]
+ lst.append(name)
+ else:
+ unknown_types[ret[0]] = [name]
+ return -1
+
+ output.write("PyObject *\n")
+ output.write("libxml_%s(PyObject *self, PyObject *args) {\n" % (name))
+ if ret[0] != 'void':
+ output.write(" PyObject *py_retval;\n")
+ if c_return != "":
+ output.write(c_return)
+ if c_args != "":
+ output.write(c_args)
+ if format != "":
+ output.write("\n if (!PyArg_ParseTuple(args, \"%s\"%s))\n" %
+ (format, format_args))
+ output.write(" return(NULL);\n")
+
+ output.write(c_call)
+ output.write(ret_convert)
+ output.write("}\n\n")
+ return 1
+
+try:
+ f = open("libxml2-api.xml")
+ data = f.read()
+ (parser, target) = getparser()
+ parser.feed(data)
+ parser.close()
+except IOError, msg:
+ print file, ":", msg
+
+print "Found %d functions in libxml2-api.xml" % (len(functions.keys()))
+nb_wrap = 0
+failed = 0
+skipped = 0
+
+wrapper = open("libxml2-py.c", "w")
+wrapper.write("/* Generated */\n\n")
+wrapper.write("#include <Python.h>\n")
+wrapper.write("#include <libxml/tree.h>\n")
+wrapper.write("#include \"libxml_wrap.h\"\n")
+wrapper.write("#include \"libxml2-py.h\"\n\n")
+for function in functions.keys():
+ ret = print_function_wrapper(function, wrapper)
+ if ret < 0:
+ failed = failed + 1
+ if ret == 1:
+ nb_wrap = nb_wrap + 1
+ if ret == 0:
+ skipped = skipped + 1
+wrapper.close()
+
+print "Generated %d wrapper functions, %d failed, %d skipped\n" % (nb_wrap,
+ failed, skipped);
+print "Missing type converters: %s" % (unknown_types.keys())
diff --git a/python/libxml.c b/python/libxml.c
new file mode 100644
index 0000000..13423f5
--- /dev/null
+++ b/python/libxml.c
@@ -0,0 +1,619 @@
+#include <Python.h>
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include "libxml_wrap.h"
+
+/* #define DEBUG */
+
+/************************************************************************
+ * *
+ * 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_charPtrWrap(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_xmlCharPtrWrap(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_xmlAttrPtrWrap(xmlAttrPtr attr) {
+ PyObject *ret;
+
+#ifdef DEBUG
+ printf("libxml_xmlNodePtrWrap: attr = %p\n", attr);
+#endif
+ if (attr == NULL) {
+ Py_INCREF(Py_None);
+ return(Py_None);
+ }
+ ret = PyCObject_FromVoidPtrAndDesc((void *) attr, "xmlAttrPtr", NULL);
+ return(ret);
+}
+
+#define PyxmlNode_Get(v) (((PyxmlNode_Object *)(v))->obj)
+
+typedef struct {
+ PyObject_HEAD
+ xmlNodePtr obj;
+} PyxmlNode_Object;
+
+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__
+};
+
+/************************************************************************
+ * *
+ * 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_xmlCharPtrWrap(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_xmlCharPtrWrap(res);
+ return resultobj;
+}
+
+/************************************************************************
+ * *
+ * The interface raw code *
+ * *
+ ************************************************************************/
+static PyObject *
+libxml_parseFile(PyObject *self, PyObject *args)
+{
+ PyObject *resultobj;
+ char *arg0;
+ xmlDocPtr result;
+
+ if (!PyArg_ParseTuple(args, "s:parseFile", &arg0))
+ return NULL;
+#ifdef DEBUG
+ printf("libxml_parseFile: arg0 = %s\n", arg0);
+#endif
+ result = (xmlDocPtr )xmlParseFile((char const *)arg0);
+ resultobj = libxml_xmlDocPtrWrap(result);
+#ifdef DEBUG
+ printf("libxml_parseFile: resultobj = %p\n", resultobj);
+#endif
+ return resultobj;
+}
+
+static PyObject *
+libxml_freeDoc(PyObject *self, PyObject *args)
+{
+ xmlDocPtr doc;
+
+ if (!PyArg_ParseTuple(args, "O:freeDoc", &doc))
+ return NULL;
+ switch(doc->type) {
+ case XML_DOCUMENT_NODE:
+ case XML_HTML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+ case XML_DOCB_DOCUMENT_NODE:
+#endif
+ xmlFreeDoc(doc);
+ break;
+ default:
+ break;
+ }
+ Py_INCREF(Py_None);
+ return(Py_None);
+}
+
+/************************************************************************
+ * *
+ * The registration stuff *
+ * *
+ ************************************************************************/
+static PyMethodDef libxmlMethods[] = {
+ { "parseFile", libxml_parseFile, METH_VARARGS },
+ { "freeDoc", libxml_freeDoc, METH_VARARGS },
+ { "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);
+}
+
diff --git a/python/libxml.py b/python/libxml.py
new file mode 100644
index 0000000..af96383
--- /dev/null
+++ b/python/libxml.py
@@ -0,0 +1,115 @@
+import _libxml
+
+class xmlNode:
+ def __init__(self, _obj=None):
+ if _obj != None:
+ self._o = _obj;
+ return
+ self._o = None
+
+# def __getattr__(self, attr):
+# attrs = {
+# 'lower': _gtk.gtk_adjustment_get_lower,
+# 'upper': _gtk.gtk_adjustment_get_upper,
+# 'value': _gtk.gtk_adjustment_get_value,
+# 'step_increment': _gtk.gtk_adjustment_get_step_increment,
+# 'page_increment': _gtk.gtk_adjustment_get_page_increment,
+# 'page_size': _gtk.gtk_adjustment_get_page_size
+# }
+# if attrs.has_key(attr):
+# ret = attrs[attr](self._o)
+# if ret == None:
+# return None
+# return attrs[attr](self._o)
+ def __getattr__(self, attr):
+ if attr == "parent":
+ ret = _libxml.parent(self._o)
+ if ret == None:
+ return None
+ return xmlNode(_obj=ret)
+ elif attr == "properties":
+ ret = _libxml.properties(self._o)
+ if ret == None:
+ return None
+ return xmlNode(_obj=ret)
+ elif attr == "children":
+ ret = _libxml.children(self._o)
+ if ret == None:
+ return None
+ return xmlNode(_obj=ret)
+ elif attr == "last":
+ ret = _libxml.last(self._o)
+ if ret == None:
+ return None
+ return xmlNode(_obj=ret)
+ elif attr == "next":
+ ret = _libxml.next(self._o)
+ if ret == None:
+ return None
+ return xmlNode(_obj=ret)
+ elif attr == "prev":
+ ret = _libxml.prev(self._o)
+ if ret == None:
+ return None
+ return xmlNode(_obj=ret)
+ elif attr == "content":
+ return self.content()
+ elif attr == "name":
+ return _libxml.name(self._o)
+ elif attr == "type":
+ return _libxml.type(self._o)
+ elif attr == "doc":
+ ret = _libxml.doc(self._o)
+ if ret == None:
+ return None
+ return xmlDoc(_doc=ret)
+ raise AttributeError,attr
+
+ #
+ # Those are common attributes to nearly all type of nodes
+ #
+ def get_parent(self):
+ ret = _libxml.parent(self._o)
+ if ret == None:
+ return None
+ return xmlNode(_obj=ret)
+ def get_children(self):
+ ret = _libxml.children(self._o)
+ if ret == None:
+ return None
+ return xmlNode(_obj=ret)
+ def get_last(self):
+ ret = _libxml.last(self._o)
+ if ret == None:
+ return None
+ return xmlNode(_obj=ret)
+ def get_next(self):
+ ret = _libxml.next(self._o)
+ if ret == None:
+ return None
+ return xmlNode(_obj=ret)
+ def get_prev(self):
+ ret = _libxml.prev(self._o)
+ if ret == None:
+ return None
+ return xmlNode(_obj=ret)
+ def get_content(self):
+ return self.content()
+ def get_name(self):
+ return _libxml.name(self._o)
+ def get_type(self):
+ return _libxml.type(self._o)
+ def get_doc(self):
+ ret = _libxml.doc(self._o)
+ if ret == None:
+ return None
+ return xmlDoc(_doc=ret)
+ def free(self):
+ _libxml.freeDoc(self._o)
+
+
+class xmlDoc(xmlNode):
+ def __init__(self, file = None, _doc=None):
+ if _doc == None and file != None:
+ _doc = _libxml.parseFile(file)
+ xmlNode.__init__(self, _obj=_doc)
diff --git a/python/libxml_wrap.h b/python/libxml_wrap.h
new file mode 100644
index 0000000..a3aca48
--- /dev/null
+++ b/python/libxml_wrap.h
@@ -0,0 +1,18 @@
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/catalog.h>
+#include <libxml/threads.h>
+#include <libxml/nanoftp.h>
+#include <libxml/nanohttp.h>
+#include <libxml/uri.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/debugXML.h>
+
+PyObject * libxml_intWrap(int val);
+PyObject * libxml_xmlCharPtrWrap(const xmlChar *str);
+PyObject * libxml_charPtrWrap(const char *str);
+PyObject * libxml_xmlDocPtrWrap(xmlDocPtr doc);
+PyObject * libxml_xmlNodePtrWrap(xmlNodePtr node);
+PyObject * libxml_xmlAttrPtrWrap(xmlAttrPtr attr);