added more informations in the libxml2-python package including docs.

* configure.in libxml.spec.in python/Makefile.am python/TODO
  python/generator.py python/libxml2class.txt: added more informations
  in the libxml2-python package including docs. Slightly changed
  the class hierarchy
* python/tests/*: added basic regression tests infrastructure too
Daniel
This commit is contained in:
Daniel Veillard 2002-02-02 09:17:16 +00:00
parent a7340c830e
commit 253aa2c33b
14 changed files with 584 additions and 20 deletions

View File

@ -1,3 +1,16 @@
Sat Feb 2 10:13:52 CET 2002 Daniel Veillard <daniel@veillard.com>
* configure.in libxml.spec.in python/Makefile.am python/TODO
python/generator.py python/libxml2class.txt: added more informations
in the libxml2-python package including docs. Slightly changed
the class hierarchy
* python/tests/*: added basic regression tests infrastructure too
Fri Feb 1 23:11:58 CET 2002 Daniel Veillard <daniel@veillard.com>
* configure.in libxml.spec.in example/Makefile.am python/Makefile.am:
added libxml2-python as part of the packages installed
Fri Feb 1 18:48:19 CET 2002 Daniel Veillard <daniel@veillard.com>
* python/Makefile.am python/generator.py python/libxml.c

View File

@ -192,6 +192,7 @@ dnl
PYTHON=
PYTHON_VERSION=
PYTHON_INCLUDES=
PYTHON_SITE_PACKAGES=
AC_ARG_WITH(python, [ --with-python[=DIR] Build Python bindings if found])
if test "$with_python" != "no" ; then
if test -x "$with_python/bin/python"
@ -208,17 +209,21 @@ if test "$with_python" != "no" ; then
fi
if test "$PYTHON_VERSION" != ""
then
if test -r $with_python/include/python$PYTHON_VERSION/Python.h
if test -r $with_python/include/python$PYTHON_VERSION/Python.h -a \
-d $with_python/lib/python$PYTHON_VERSION/site-packages
then
PYTHON_INCLUDES=$with_python/include/python$PYTHON_VERSION
PYTHON_SITE_PACKAGES=$with_python/lib/python$PYTHON_VERSION/site-packages
else
if test -r $prefix/include/python$PYTHON_VERSION/Python.h
then
PYTHON_INCLUDES=$prefix/include/python$PYTHON_VERSION
PYTHON_INCLUDES='$(prefix)/include/python$(PYTHON_VERSION)'
PYTHON_SITE_PACKAGES='$(prefix)/lib/python$(PYTHON_VERSION)/site-packages'
else
if test -r /usr/include/python$PYTHON_VERSION/Python.h
then
PYTHON_INCLUDES=/usr/include/python$PYTHON_VERSION
PYTHON_SITE_PACKAGES=/usr/lib/python$PYTHON_VERSION/site-packages
else
echo could not find python$PYTHON_VERSION/Python.h
fi
@ -528,9 +533,10 @@ AC_SUBST(HAVE_ISINF)
AC_SUBST(PYTHON)
AC_SUBST(PYTHON_VERSION)
AC_SUBST(PYTHON_INCLUDES)
AC_SUBST(PYTHON_SITE_PACKAGES)
AC_SUBST(M_LIBS)
AC_SUBST(RDL_LIBS)
AC_OUTPUT(libxml.spec Makefile include/Makefile include/libxml/Makefile doc/Makefile example/Makefile python/Makefile include/libxml/xmlversion.h include/libxml/xmlwin32version.h xml2-config libxml-2.0.pc xml2Conf.sh)
AC_OUTPUT(libxml.spec Makefile include/Makefile include/libxml/Makefile doc/Makefile example/Makefile python/Makefile python/tests/Makefile include/libxml/xmlversion.h include/libxml/xmlwin32version.h xml2-config libxml-2.0.pc xml2Conf.sh)

View File

@ -1,4 +1,4 @@
AUTOMAKE_OPTIONS=no-dependencies
# AUTOMAKE_ OPTIONS=no-dependencies
noinst_PROGRAMS = gjobread

View File

@ -6,6 +6,7 @@ License: LGPL
Group: Development/Libraries
Source: ftp://xmlsoft.org/libxml2-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-root
BuildRequires: python python-devel
URL: http://xmlsoft.org/
Prefix: %{_prefix}
Docdir: %{_docdir}
@ -38,6 +39,21 @@ to select subnodes or ranges. A flexible Input/Output mechanism is
available, with existing HTTP and FTP modules and combined to an
URI library.
%package python
Summary: Python bindings for the libxml2 library
Group: Development/Libraries
Requires: libxml2 = %{version}
Requires: python
%description python
The libxml2-python package contains a module that permits applications
written in the Python programming language to use the interface
supplied by the libxml2 library to manipulate XML files.
This library allows to manipulate XML files. It includes support
to read, modify and write XML and HTML files. There is DTDs support
this includes parsing and validation even with complex DTDs, either
at parse time or later once the document has been modified.
%prep
%setup -q
@ -103,8 +119,19 @@ rm -rf $RPM_BUILD_ROOT
%{prefix}/bin/xml2-config
%{prefix}/share/aclocal/libxml.m4
%{prefix}/lib/pkgconfig/libxml-2.0.pc
%files python
%defattr(-, root, root)
%{prefix}/lib/python*/site-packages/libxml2.py
%{prefix}/lib/python*/site-packages/_libxml.so
%doc python/TODO
%doc python/libxml2class.txt
%doc python/tests/*.py
%changelog
* Fri Feb 1 2002 Daniel Veillard <veillard@redhat.com>
- Added the python package
* Sun Nov 4 2001 Daniel Veillard <veillard@redhat.com>

View File

@ -1,19 +1,25 @@
SUBDIRS= . tests
LIBS=-L../.libs -L.. $(XML_LIBS)
INCLUDES=-I$(PYTHON_INCLUDES) -I$(top_srcdir)/include
INCLUDES=-I/usr/include/python$(PYTHON_VERSION) -I$(PYTHON_INCLUDES) -I$(top_srcdir)/include
SHCFLAGS=$(INCLUDES) -Wall -fPIC
LINK_FLAGS= -shared
DOCS_DIR = $(prefix)/share/doc/libxml2-python-$(LIBXML_VERSION)
DOCS = TODO libxml2class.txt
EXTRA_DIST = \
libxml.c \
generator.py \
libxml_wrap.h \
libxml.py
libxml.py \
$(DOCS)
if WITH_PYTHON
all: _libxml.so libxml2.py
libxml2.py: libxml.py libxml2class.py
cat libxml.py libxml2class.py > libxml2.py
libxml2.py: $(srcdir)/libxml.py libxml2class.py
cat $(srcdir)/libxml.py libxml2class.py > libxml2.py
_libxml.so: libxml.o libxml2-py.o
$(CC) $(LINK_FLAGS) libxml2-py.o libxml.o $(LIBS) -o _libxml.so
@ -39,3 +45,12 @@ $(GENERATED): $(srcdir)/$(GENERATE) $(API_DESC)
clean:
rm -f $(GENERATED) *.o _libxml.so *.pyc libxml2.py
install-data-local:
$(mkinstalldirs) $(DESTDIR)$(PYTHON_SITE_PACKAGES)
-@INSTALL@ -m 0644 libxml2.py $(DESTDIR)$(PYTHON_SITE_PACKAGES)
-@INSTALL@ -m 0755 _libxml.so $(DESTDIR)$(PYTHON_SITE_PACKAGES)
$(mkinstalldirs) $(DESTDIR)$(DOCS_DIR)
-@(for doc in $(DOCS) ; \
do @INSTALL@ -m 0644 $$doc $(DESTDIR)$(DOCS_DIR) ; done)

41
python/TODO Normal file
View File

@ -0,0 +1,41 @@
TODO for the libxml2 Python wrappers
$Id$
Things to do:
-------------
- handling of node.content
- SAX interfaces
- error redirections and preformat
- class hierarchy:
+ get the generator to output a classes.txt description
- extensions based on a python.xml description of the new specific
interfaces
- memory debug interfaces
- enums -> libxml.py
- spec file: automatically generate for pythonX.Y if found
- access to XPath variables
- parserCtxt exposure:
- entry points
- wrappers
- decent interface for setting/getting behaviour
- xmlBuffer exposure
- xpathContext, being able to set/get info and clean it up
- add regression tests
- check memory
- build tree
- saving
- SAX flow
Done:
-----
- class hierarchy:
+ make specific node type inherit from xmlNode
- add regression tests
- tests/Makefile.am: export the Python class path
- xpath queries
- xpath extension
Daniel Veillard

View File

@ -210,11 +210,11 @@ py_types = {
'double': ('d', None, "double", "double"),
'unsigned int': ('i', None, "int", "int"),
'xmlChar': ('c', None, "int", "int"),
'unsigned char *': ('s', None, "charPtr", "char *"),
'char *': ('s', None, "charPtr", "char *"),
'const char *': ('s', None, "charPtr", "char *"),
'xmlChar *': ('s', None, "xmlCharPtr", "xmlChar *"),
'const xmlChar *': ('s', None, "xmlCharPtr", "xmlChar *"),
'unsigned char *': ('z', None, "charPtr", "char *"),
'char *': ('z', None, "charPtr", "char *"),
'const char *': ('z', None, "charPtr", "char *"),
'xmlChar *': ('z', None, "xmlCharPtr", "xmlChar *"),
'const xmlChar *': ('z', None, "xmlCharPtr", "xmlChar *"),
'xmlNodePtr': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
'const xmlNodePtr': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
'xmlNode *': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
@ -465,13 +465,13 @@ primary_classes = ["xmlNode", "xmlDoc"]
classes_ancestor = {
"xmlNode" : "xmlCore",
"xmlDoc" : "xmlCore",
"xmlAttr" : "xmlCore",
"xmlNs" : "xmlCore",
"xmlDtd" : "xmlCore",
"xmlEntity" : "xmlCore",
"xmlElement" : "xmlCore",
"xmlAttribute" : "xmlCore",
"xmlDtd" : "xmlNode",
"xmlDoc" : "xmlNode",
"xmlAttr" : "xmlNode",
"xmlNs" : "xmlNode",
"xmlEntity" : "xmlNode",
"xmlElement" : "xmlNode",
"xmlAttribute" : "xmlNode",
}
classes_destructors = {
"xpathContext": "xmlXPathFreeContext",
@ -574,6 +574,8 @@ for name in functions.keys():
function_classes['None'].append(info)
classes = open("libxml2class.py", "w")
txt = open("libxml2class.txt", "w")
txt.write(" Generated Classes for libxml2-python\n\n")
def functionCompare(info1, info2):
(index1, func1, name1, ret1, args1, file1) = info1
@ -608,6 +610,7 @@ def writeDoc(name, args, indent, output):
output.write(val);
output.write('"""\n')
txt.write("#\n# Global functions of the module\n#\n\n")
if function_classes.has_key("None"):
flist = function_classes["None"]
flist.sort(functionCompare)
@ -616,8 +619,10 @@ if function_classes.has_key("None"):
(index, func, name, ret, args, file) = info
if file != oldfile:
classes.write("#\n# Functions from module %s\n#\n\n" % file)
txt.write("\n# functions from module %s\n" % file)
oldfile = file
classes.write("def %s(" % func)
txt.write("%s()\n" % func);
n = 0
for arg in args:
if n != 0:
@ -650,11 +655,14 @@ if function_classes.has_key("None"):
classes.write(" return ret\n");
classes.write("\n");
txt.write("\n\n#\n# Set of classes of the module\n#\n\n")
for classname in function_classes.keys():
if classname == "None":
pass
else:
if classes_ancestor.has_key(classname):
txt.write("\n\nClass %s(%s)\n" % (classname,
classes_ancestor[classname]))
classes.write("class %s(%s):\n" % (classname,
classes_ancestor[classname]))
classes.write(" def __init__(self, _obj=None):\n")
@ -662,6 +670,7 @@ for classname in function_classes.keys():
classes.write(" %s.__init__(self, _obj=_obj)\n\n" % (
classes_ancestor[classname]))
else:
txt.write("Class %s()\n" % (classname))
classes.write("class %s:\n" % (classname))
classes.write(" def __init__(self, _obj=None):\n")
classes.write(" if _obj != None:self._o = _obj;return\n")
@ -685,9 +694,11 @@ for classname in function_classes.keys():
classes.write(" #\n")
classes.write(" # %s functions from module %s\n" % (
classname, file))
txt.write("\n # functions from module %s\n" % file)
classes.write(" #\n\n")
oldfile = file
classes.write(" def %s(self" % func)
txt.write(" %s()\n" % func);
n = 0
for arg in args:
if n != index:
@ -727,4 +738,5 @@ for classname in function_classes.keys():
classes.write(" return ret\n");
classes.write("\n");
txt.close()
classes.close()

330
python/libxml2class.txt Normal file
View File

@ -0,0 +1,330 @@
Generated Classes for libxml2-python
#
# Global functions of the module
#
# functions from module HTMLparser
htmlHandleOmittedElem()
htmlIsScriptAttribute()
htmlParseDoc()
htmlParseFile()
# functions from module HTMLtree
htmlNewDoc()
htmlNewDocNoDtD()
# functions from module catalog
catalogAdd()
catalogCleanup()
catalogConvert()
catalogGetPublic()
catalogGetSystem()
catalogRemove()
catalogResolve()
catalogResolvePublic()
catalogResolveSystem()
catalogResolveURI()
catalogSetDebug()
initializeCatalog()
loadCatalog()
loadCatalogs()
parseCatalogFile()
# functions from module debugXML
shellPrintXPathError()
# functions from module encoding
UTF8Strlen()
UTF8Strloc()
UTF8Strndup()
UTF8Strpos()
UTF8Strsize()
UTF8Strsub()
addEncodingAlias()
checkUTF8()
cleanupCharEncodingHandlers()
cleanupEncodingAliases()
delEncodingAlias()
encodingAlias()
initCharEncodingHandlers()
# functions from module entities
cleanupPredefinedEntities()
initializePredefinedEntities()
predefinedEntity()
# functions from module nanoftp
nanoFTPCleanup()
nanoFTPInit()
nanoFTPProxy()
nanoFTPScanProxy()
# functions from module nanohttp
nanoHTTPCleanup()
nanoHTTPInit()
nanoHTTPScanProxy()
# functions from module parser
cleanupParser()
defaultSAXHandlerInit()
htmlDefaultSAXHandlerInit()
initParser()
keepBlanksDefault()
lineNumbersDefault()
parseDTD()
parseDoc()
parseEntity()
parseFile()
parseMemory()
pedanticParserDefault()
recoverDoc()
recoverFile()
recoverMemory()
substituteEntitiesDefault()
# functions from module parserInternals
checkLanguageID()
copyChar()
copyCharMultiByte()
htmlInitAutoClose()
isBaseChar()
isBlank()
isChar()
isCombining()
isDigit()
isExtender()
isIdeographic()
isLetter()
isPubidChar()
# functions from module tree
compressMode()
newComment()
newDoc()
newPI()
newText()
newTextLen()
setCompressMode()
# functions from module uri
URIEscape()
URIEscapeStr()
URIUnescapeString()
buildURI()
normalizeURIPath()
# functions from module xmlIO
cleanupInputCallbacks()
cleanupOutputCallbacks()
parserGetDirectory()
registerDefaultInputCallbacks()
registerDefaultOutputCallbacks()
registerHTTPPostCallbacks()
# functions from module xmlversion
checkVersion()
#
# Set of classes of the module
#
Class xpathContext()
# functions from module xpath
xpathEval()
xpathEvalExpression()
# functions from module xpathInternals
xpathFreeContext()
xpathNsLookup()
xpathRegisterAllFunctions()
xpathRegisterNs()
xpathRegisteredFuncsCleanup()
xpathRegisteredNsCleanup()
xpathRegisteredVariablesCleanup()
xpathVariableLookup()
xpathVariableLookupNS()
Class xmlDoc(xmlNode)
# functions from module HTMLparser
htmlAutoCloseTag()
htmlIsAutoClosed()
# functions from module HTMLtree
htmlGetMetaEncoding()
htmlSaveFile()
htmlSaveFileEnc()
htmlSaveFileFormat()
htmlSetMetaEncoding()
# functions from module entities
addDocEntity()
addDtdEntity()
docEntity()
dtdEntity()
encodeEntities()
encodeEntitiesReentrant()
encodeSpecialChars()
parameterEntity()
# functions from module tree
copyDoc()
createIntSubset()
docCompressMode()
freeDoc()
getRootElement()
intSubset()
newCDataBlock()
newCharRef()
newDocComment()
newDocFragment()
newDocNode()
newDocProp()
newDocRawNode()
newDocText()
newDocTextLen()
newDtd()
newGlobalNs()
newReference()
saveFile()
saveFileEnc()
saveFormatFile()
saveFormatFileEnc()
setDocCompressMode()
stringGetNodeList()
stringLenGetNodeList()
# functions from module valid
ID()
isMixedElement()
removeID()
removeRef()
# functions from module xinclude
xincludeProcess()
# functions from module xpathInternals
xpathNewContext()
Class xmlNode(xmlCore)
# functions from module debugXML
lsCountNode()
shellPrintNode()
# functions from module tree
addChild()
addChildList()
addContent()
addContentLen()
addNextSibling()
addPrevSibling()
addSibling()
copyNode()
copyNodeList()
copyProp()
copyPropList()
docCopyNode()
docSetRootElement()
freeNode()
freeNodeList()
getBase()
getContent()
getLang()
getSpacePreserve()
hasNsProp()
hasProp()
isBlankNode()
isText()
lastChild()
lineNo()
listGetRawString()
listGetString()
newChild()
newNs()
newNsProp()
newProp()
newTextChild()
nodePath()
nsProp()
prop()
reconciliateNs()
replaceNode()
searchNs()
searchNsByHref()
setBase()
setContent()
setContentLen()
setLang()
setListDoc()
setName()
setNs()
setNsProp()
setProp()
setSpacePreserve()
setTreeDoc()
textConcat()
textMerge()
unlinkNode()
unsetNsProp()
unsetProp()
# functions from module valid
isID()
isRef()
validNormalizeAttributeValue()
# functions from module xpath
xpathCastNodeToNumber()
xpathCastNodeToString()
xpathCmpNodes()
# functions from module xpathInternals
xpathNewNodeSet()
xpathNewValueTree()
Class xmlAttribute(xmlNode)
Class xmlDtd(xmlNode)
# functions from module tree
copyDtd()
freeDtd()
# functions from module valid
dtdAttrDesc()
dtdElementDesc()
dtdQAttrDesc()
dtdQElementDesc()
Class xmlAttr(xmlNode)
# functions from module tree
freeProp()
freePropList()
removeProp()
Class xmlEntity(xmlNode)
Class xmlElement(xmlNode)
Class xmlNs(xmlNode)
# functions from module tree
copyNamespace()
copyNamespaceList()
freeNs()
freeNsList()
newNode()

26
python/tests/Makefile.am Normal file
View File

@ -0,0 +1,26 @@
EXAMPLE_DIR = $(prefix)/share/doc/libxml2-python-$(LIBXML_VERSION)/examples
TESTS= \
tst.py \
tstxpath.py \
xpathext.py \
xpath.py
XMLS= \
tst.xml
EXTRA_DIST = $(TESTS) $(XMLS)
if WITH_PYTHON
tests: $(TESTS)
-@(CLASSPATH=".." ; export CLASSPATH; \
for test in $(TESTS) ; do echo "-- $$test" ; $(PYTHON) $$test ; done)
else
tests:
endif
install-data-local:
$(mkinstalldirs) $(DESTDIR)$(EXAMPLE_DIR)
-(for test in $(TESTS) $(XMLS); \
do @INSTALL@ -m 0644 $$test $(DESTDIR)$(EXAMPLE_DIR) ; done)

10
python/tests/tst.py Executable file
View File

@ -0,0 +1,10 @@
#!/usr/bin/python -u
import libxml2
doc = libxml2.parseFile("tst.xml")
print doc.name
root = doc.children
print root.name
child = root.children
print child.name
doc.freeDoc()

1
python/tests/tst.xml Normal file
View File

@ -0,0 +1 @@
<doc><foo>bar</foo></doc>

29
python/tests/tstxpath.py Executable file
View File

@ -0,0 +1,29 @@
#!/usr/bin/python -u
import libxml2
def foo(x):
# print "foo called %s" % (x)
return x + 1
def bar(x):
# print "foo called %s" % (x)
return "%s" % (x + 1)
doc = libxml2.parseFile("tst.xml")
ctxt = doc.xpathNewContext()
res = ctxt.xpathEval("//*")
print res
libxml2.registerXPathFunction(ctxt._o, "foo", None, foo)
libxml2.registerXPathFunction(ctxt._o, "bar", None, bar)
i = 10000
while i > 0:
res = ctxt.xpathEval("foo(1)")
i = i - 1
print res
i = 10000
while i > 0:
res = ctxt.xpathEval("bar(1)")
i = i - 1
print res
doc.freeDoc()

21
python/tests/xpath.py Executable file
View File

@ -0,0 +1,21 @@
#!/usr/bin/python -u
#
# this test exercise the XPath basic engine, parser, etc, and
# allows to detect memory leaks
#
import libxml2
doc = libxml2.parseFile("tst.xml")
print doc
i = 1000
while i > 0:
doc = libxml2.parseFile("tst.xml")
ctxt = doc.xpathNewContext()
res = ctxt.xpathEval("//*")
doc.freeDoc()
i = i -1
doc = libxml2.parseFile("tst.xml")
ctxt = doc.xpathNewContext()
res = ctxt.xpathEval("//*")
print res
doc.freeDoc()

33
python/tests/xpathext.py Executable file
View File

@ -0,0 +1,33 @@
#!/usr/bin/python -u
#
# This test exercise the extension of the XPath engine with
# functions defined in Python.
#
import libxml2
def foo(x):
# print "foo called %s" % (x)
return x + 1
def bar(x):
# print "foo called %s" % (x)
return "%s" % (x + 1)
doc = libxml2.parseFile("tst.xml")
ctxt = doc.xpathNewContext()
res = ctxt.xpathEval("//*")
print res
libxml2.registerXPathFunction(ctxt._o, "foo", None, foo)
libxml2.registerXPathFunction(ctxt._o, "bar", None, bar)
i = 10000
while i > 0:
res = ctxt.xpathEval("foo(1)")
i = i - 1
print res
i = 10000
while i > 0:
res = ctxt.xpathEval("bar(1)")
i = i - 1
print res
doc.freeDoc()