added the close and getattribute methods of XmlTextReader. added the
* xmlreader.c doc/libxml2-api.xml: added the close and getattribute
methods of XmlTextReader.
* python/generator.py python/libxml_wrap.h python/types.c
python/libxml2class.txt: added the reader to the Python bindings
* python/tests/Makefile.am python/tests/reader.py: added a specific
test for the Python bindings of the Reader APIs
* parser.c: small cleanup.
Daniel
diff --git a/python/generator.py b/python/generator.py
index 9c75713..b42630b 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -271,6 +271,7 @@
'xmlOutputBufferPtr': ('O', "outputBuffer", "xmlOutputBufferPtr", "xmlOutputBufferPtr"),
'xmlParserInputBufferPtr': ('O', "inputBuffer", "xmlParserInputBufferPtr", "xmlParserInputBufferPtr"),
'xmlRegexpPtr': ('O', "xmlReg", "xmlRegexpPtr", "xmlRegexpPtr"),
+ 'xmlTextReaderPtr': ('O', "xmlTextReader", "xmlTextReaderPtr", "xmlTextReaderPtr"),
}
py_return_types = {
@@ -597,6 +598,7 @@
"xmlOutputBufferPtr": ("._o", "outputBuffer(_obj=%s)", "outputBuffer"),
"xmlParserInputBufferPtr": ("._o", "inputBuffer(_obj=%s)", "inputBuffer"),
"xmlRegexpPtr": ("._o", "xmlReg(_obj=%s)", "xmlReg"),
+ "xmlTextReaderPtr": ("._o", "xmlTextReader(_obj=%s)", "xmlTextReader"),
}
converter_type = {
@@ -624,6 +626,7 @@
# "outputBuffer": "xmlOutputBufferClose",
"inputBuffer": "xmlFreeParserInputBuffer",
"xmlReg": "xmlRegFreeRegexp",
+ "xmlTextReader": "xmlFreeTextReader",
}
functions_noexcept = {
@@ -676,6 +679,9 @@
func = "regexp" + name[9:]
elif name[0:6] == "xmlReg" and file == "xmlregexp":
func = "regexp" + name[6:]
+ elif name[0:13] == "xmlTextReader" and file == "xmlreader":
+ func = name[13:]
+ func = string.lower(func[0:1]) + func[1:]
elif name[0:11] == "xmlACatalog":
func = name[11:]
func = string.lower(func[0:1]) + func[1:]
diff --git a/python/libxml2class.txt b/python/libxml2class.txt
index e15f599..6127f7b 100644
--- a/python/libxml2class.txt
+++ b/python/libxml2class.txt
@@ -165,6 +165,9 @@
registerDefaultOutputCallbacks()
registerHTTPPostCallbacks()
+# functions from module xmlreader
+newTextReaderFilename()
+
# functions from module xmlregexp
regexpCompile()
@@ -556,6 +559,30 @@
freeProp()
freePropList()
removeProp()
+Class xmlTextReader()
+
+ # functions from module xmlreader
+ attributeCount()
+ baseUri()
+ close()
+ depth()
+ freeTextReader()
+ getAttribute()
+ getAttributeNo()
+ getAttributeNs()
+ hasAttributes()
+ hasValue()
+ isDefault()
+ isEmptyElement()
+ localName()
+ name()
+ namespaceUri()
+ nodeType()
+ prefix()
+ quoteChar()
+ read()
+ value()
+ xmlLang()
Class xmlReg()
# functions from module xmlregexp
@@ -731,6 +758,9 @@
push()
read()
+ # functions from module xmlreader
+ newTextReader()
+
Class outputBuffer(ioWriteWrapper)
diff --git a/python/libxml_wrap.h b/python/libxml_wrap.h
index efa79d0..7a38f54 100644
--- a/python/libxml_wrap.h
+++ b/python/libxml_wrap.h
@@ -17,6 +17,26 @@
#include <libxml/xmlunicode.h>
#include <libxml/xmlregexp.h>
#include <libxml/xmlautomata.h>
+#include <libxml/xmlreader.h>
+
+/**
+ * ATTRIBUTE_UNUSED:
+ *
+ * Macro used to signal to GCC unused function parameters
+ * Repeated here since the definition is not available when
+ * compiled outside the libxml2 build tree.
+ */
+#ifdef __GNUC__
+#ifdef ATTRIBUTE_UNUSED
+#undef ATTRIBUTE_UNUSED
+#endif
+#include <ansidecl.h>
+#ifndef ATTRIBUTE_UNUSED
+#define ATTRIBUTE_UNUSED
+#endif
+#else
+#define ATTRIBUTE_UNUSED
+#endif
#define PyxmlNode_Get(v) (((v) == Py_None) ? NULL : \
(((PyxmlNode_Object *)(v))->obj))
@@ -66,6 +86,14 @@
xmlRegexpPtr obj;
} PyxmlReg_Object;
+#define PyxmlTextReader_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyxmlTextReader_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlTextReaderPtr obj;
+} PyxmlTextReader_Object;
+
#define PyURI_Get(v) (((v) == Py_None) ? NULL : \
(((PyURI_Object *)(v))->obj))
@@ -119,5 +147,6 @@
PyObject * libxml_xmlOutputBufferPtrWrap(xmlOutputBufferPtr buffer);
PyObject * libxml_xmlParserInputBufferPtrWrap(xmlParserInputBufferPtr buffer);
PyObject * libxml_xmlRegexpPtrWrap(xmlRegexpPtr regexp);
+PyObject * libxml_xmlTextReaderPtrWrap(xmlTextReaderPtr reader);
xmlXPathObjectPtr libxml_xmlXPathObjectPtrConvert(PyObject * obj);
diff --git a/python/tests/Makefile.am b/python/tests/Makefile.am
index 96cb033..c6bef2c 100644
--- a/python/tests/Makefile.am
+++ b/python/tests/Makefile.am
@@ -19,7 +19,8 @@
outbuf.py \
inbuf.py \
resolver.py \
- regexp.py
+ regexp.py \
+ reader.py
XMLS= \
tst.xml \
diff --git a/python/tests/reader.py b/python/tests/reader.py
new file mode 100755
index 0000000..1817fe9
--- /dev/null
+++ b/python/tests/reader.py
@@ -0,0 +1,94 @@
+#!/usr/bin/python -u
+import libxml2
+import StringIO
+import sys
+
+# Memory debug specific
+libxml2.debugMemory(1)
+
+f = StringIO.StringIO("""<a><b b1="b1"/><c>content of c</c></a>""")
+input = libxml2.inputBuffer(f)
+reader = input.newTextReader()
+ret = reader.read()
+if ret != 1:
+ print "Error reading to first element"
+ sys.exit(1)
+if reader.name() != "a" or reader.isEmptyElement() != 0 or \
+ reader.nodeType() != 1 or reader.hasAttributes() != 0:
+ print "Error reading the first element"
+ sys.exit(1)
+ret = reader.read()
+if ret != 1:
+ print "Error reading to second element"
+ sys.exit(1)
+if reader.name() != "b" or reader.isEmptyElement() != 1 or \
+ reader.nodeType() != 1 or reader.hasAttributes() != 1:
+ print "Error reading the second element"
+ sys.exit(1)
+ret = reader.read()
+if ret != 1:
+ print "Error reading to third element"
+ sys.exit(1)
+if reader.name() != "c" or reader.isEmptyElement() != 0 or \
+ reader.nodeType() != 1 or reader.hasAttributes() != 0:
+ print "Error reading the third element"
+ sys.exit(1)
+ret = reader.read()
+if ret != 1:
+ print "Error reading to text node"
+ sys.exit(1)
+if reader.name() != "#text" or reader.isEmptyElement() != 0 or \
+ reader.nodeType() != 3 or reader.hasAttributes() != 0 or \
+ reader.value() != "content of c":
+ print "Error reading the text node"
+ sys.exit(1)
+ret = reader.read()
+if ret != 1:
+ print "Error reading to end of third element"
+ sys.exit(1)
+if reader.name() != "c" or reader.isEmptyElement() != 0 or \
+ reader.nodeType() != 15 or reader.hasAttributes() != 0:
+ print "Error reading the end of third element"
+ sys.exit(1)
+ret = reader.read()
+if ret != 1:
+ print "Error reading to end of first element"
+ sys.exit(1)
+if reader.name() != "a" or reader.isEmptyElement() != 0 or \
+ reader.nodeType() != 15 or reader.hasAttributes() != 0:
+ print "Error reading the end of first element"
+ sys.exit(1)
+ret = reader.read()
+if ret != 0:
+ print "Error reading to end of document"
+ sys.exit(1)
+
+#
+# example from the XmlTextReader docs
+#
+f = StringIO.StringIO("""<test xmlns:dt="urn:datatypes" dt:type="int"/>""")
+input = libxml2.inputBuffer(f)
+reader = input.newTextReader()
+
+ret = reader.read()
+if ret != 1:
+ print "Error reading test element"
+ sys.exit(1)
+if reader.getAttributeNo(0) != "urn:datatypes" or \
+ reader.getAttributeNo(1) != "int" or \
+ reader.getAttributeNs("type", "urn:datatypes") != "int" or \
+ reader.getAttribute("dt:type") != "int":
+ print "error reading test attributes"
+ sys.exit(1)
+
+del f
+del input
+del reader
+
+# Memory debug specific
+libxml2.cleanupParser()
+if libxml2.debugMemory(1) == 0:
+ print "OK"
+else:
+ print "Memory leak %d bytes" % (libxml2.debugMemory(1))
+ libxml2.dumpMemory()
diff --git a/python/types.c b/python/types.c
index 3f49028..2c5a13e 100644
--- a/python/types.c
+++ b/python/types.c
@@ -547,3 +547,21 @@
(char *) "xmlRegexpPtr", NULL);
return (ret);
}
+
+PyObject *
+libxml_xmlTextReaderPtrWrap(xmlTextReaderPtr reader)
+{
+ PyObject *ret;
+
+#ifdef DEBUG
+ printf("libxml_xmlTextReaderPtrWrap: reader = %p\n", reader);
+#endif
+ if (reader == NULL) {
+ Py_INCREF(Py_None);
+ return (Py_None);
+ }
+ ret =
+ PyCObject_FromVoidPtrAndDesc((void *) reader,
+ (char *) "xmlTextReaderPtr", NULL);
+ return (ret);
+}