[libxml2]Add libxml2 library

This commit is contained in:
zhoujiale
2026-07-26 16:57:28 +08:00
committed by zhoujiale
parent 0a44ec8a06
commit e841ac915d
3790 changed files with 668244 additions and 0 deletions
+77
View File
@@ -0,0 +1,77 @@
PYTESTS= \
build.py \
attribs.py \
tst.py \
tstxpath.py \
xpathext.py \
push.py \
pushSAX.py \
pushSAXhtml.py \
error.py \
serialize.py\
validate.py \
tstURI.py \
cutnpaste.py\
xpathret.py \
xpath.py \
outbuf.py \
inbuf.py \
input_callback.py \
resolver.py \
regexp.py \
reader.py \
reader2.py \
reader3.py \
reader4.py \
reader5.py \
reader6.py \
reader7.py \
reader8.py \
readernext.py \
walker.py \
nsdel.py \
ctxterror.py\
readererr.py\
relaxng.py \
schema.py \
thread2.py \
sync.py \
tstLastError.py \
indexes.py \
dtdvalid.py \
tstmem.py \
validDTD.py \
validSchemas.py \
validRNG.py \
compareNodes.py \
xpathns.py \
xpathleak.py \
unicode.py
XMLS= \
tst.xml \
valid.xml \
invalid.xml \
test.dtd
EXTRA_DIST = $(PYTESTS) $(XMLS) setup_test.py
CLEANFILES = core tmp.xml *.pyc
if WITH_PYTHON
check-local:
@for f in $(XMLS) ; do test -f $$f || $(LN_S) $(srcdir)/$$f . ; done
@echo "## running Python regression tests"
@(export PYTHONPATH="..:../.libs:$(srcdir)/..:$$PYTHONPATH" ; \
export LD_LIBRARY_PATH="$(top_builddir)/.libs:$$LD_LIBRARY_PATH" ; \
export DYLD_LIBRARY_PATH="$(top_builddir)/.libs:$$DYLD_LIBRARY_PATH" ; \
export PATH="$(top_builddir)/.libs:$$PATH" ; \
for test in $(PYTESTS) ; do \
log=`$(PYTHON) $(srcdir)/$$test` ; \
if [ "$$?" -ne 0 ] ; then \
echo "-- $$test" ; \
echo "$$log" ; \
exit 1 ; \
fi ; \
done)
endif
+35
View File
@@ -0,0 +1,35 @@
#!/usr/bin/env python3
import sys
import setup_test
import libxml2
# Memory debug specific
libxml2.debugMemory(1)
#
# Testing XML document serialization
#
doc = libxml2.readDoc(
"""<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE test [
<!ELEMENT test (#PCDATA) >
<!ATTLIST test xmlns:abc CDATA #FIXED "http://abc.org" >
<!ATTLIST test abc:attr CDATA #FIXED "def" >
]>
<test />
""", None, None, libxml2.XML_PARSE_DTDATTR)
elem = doc.getRootElement()
attr = elem.hasNsProp('attr', 'http://abc.org')
print(attr.serialize())
if attr == None:
print("Failed to find defaulted attribute abc:attr")
sys.exit(1)
doc.freeDoc()
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+59
View File
@@ -0,0 +1,59 @@
#!/usr/bin/env python3
import setup_test
import libxml2
import sys
# Memory debug specific
libxml2.debugMemory(1)
doc = libxml2.newDoc("1.0")
comment = doc.newDocComment("This is a generated document")
doc.addChild(comment)
pi = libxml2.newPI("test", "PI content")
doc.addChild(pi)
root = doc.newChild(None, "doc", None)
ns = root.newNs("http://example.com/doc", "my")
root.setNs(ns)
elem = root.newChild(None, "foo", "bar")
elem.setBase("http://example.com/imgs")
elem.setProp("img", "image.gif")
doc.saveFile("tmp.xml")
doc.freeDoc()
doc = libxml2.parseFile("tmp.xml")
comment = doc.children
if comment.type != "comment" or \
comment.content != "This is a generated document":
print("error rereading comment")
sys.exit(1)
pi = comment.next
if pi.type != "pi" or pi.name != "test" or pi.content != "PI content":
print("error rereading PI")
sys.exit(1)
root = pi.next
if root.name != "doc":
print("error rereading root")
sys.exit(1)
ns = root.ns()
if ns.name != "my" or ns.content != "http://example.com/doc":
print("error rereading namespace")
sys.exit(1)
elem = root.children
if elem.name != "foo":
print("error rereading elem")
sys.exit(1)
if elem.getBase(None) != "http://example.com/imgs":
print("error rereading base")
sys.exit(1)
if elem.prop("img") != "image.gif":
print("error rereading property")
sys.exit(1)
doc.freeDoc()
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+50
View File
@@ -0,0 +1,50 @@
#!/usr/bin/env python3
import sys
import setup_test
import libxml2
# Memory debug specific
libxml2.debugMemory(1)
#
# Testing XML Node comparison and Node hash-value
#
doc = libxml2.parseDoc("""<root><foo/></root>""")
root = doc.getRootElement()
# Create two different objects which point to foo
foonode1 = root.children
foonode2 = root.children
# Now check that [in]equality tests work ok
if not ( foonode1 == foonode2 ):
print("Error comparing nodes with ==, nodes should be equal but are unequal")
sys.exit(1)
if not ( foonode1 != root ):
print("Error comparing nodes with ==, nodes should not be equal but are equal")
sys.exit(1)
if not ( foonode1 != root ):
print("Error comparing nodes with !=, nodes should not be equal but are equal")
if ( foonode1 != foonode2 ):
print("Error comparing nodes with !=, nodes should be equal but are unequal")
# Next check that the hash function for the objects also works ok
if not (hash(foonode1) == hash(foonode2)):
print("Error hash values for two equal nodes are different")
sys.exit(1)
if not (hash(foonode1) != hash(root)):
print("Error hash values for two unequal nodes are not different")
sys.exit(1)
if hash(foonode1) == hash(root):
print("Error hash values for two unequal nodes are equal")
sys.exit(1)
# Basic tests successful
doc.freeDoc()
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+56
View File
@@ -0,0 +1,56 @@
#!/usr/bin/env python3
#
# This test exercise the redirection of error messages with a
# functions defined in Python.
#
import sys
import setup_test
import libxml2
# Memory debug specific
libxml2.debugMemory(1)
expect="""--> (3) xmlns: URI foo is not absolute
--> (4) Opening and ending tag mismatch: x line 1 and y
"""
err=""
def callback(arg,msg,severity,reserved):
global err
err = err + "%s (%d) %s" % (arg,severity,msg)
s = """<x xmlns="foo"></y>"""
parserCtxt = libxml2.createPushParser(None,"",0,"test.xml")
parserCtxt.setErrorHandler(callback, "-->")
if parserCtxt.getErrorHandler() != (callback,"-->"):
print("getErrorHandler failed")
sys.exit(1)
parserCtxt.parseChunk(s,len(s),1)
doc = parserCtxt.doc()
doc.freeDoc()
parserCtxt = None
if err != expect:
print("error")
print("received %s" %(err))
print("expected %s" %(expect))
sys.exit(1)
i = 10000
while i > 0:
parserCtxt = libxml2.createPushParser(None,"",0,"test.xml")
parserCtxt.setErrorHandler(callback, "-->")
parserCtxt.parseChunk(s,len(s),1)
doc = parserCtxt.doc()
doc.freeDoc()
parserCtxt = None
err = ""
i = i - 1
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+48
View File
@@ -0,0 +1,48 @@
#!/usr/bin/env python3
import sys
import setup_test
import libxml2
# Memory debug specific
libxml2.debugMemory(1)
#
# Testing XML document serialization
#
source = libxml2.parseDoc("""<?xml version="1.0"?>
<root xmlns:foo="http://example.org/foo"
xmlns:bar="http://example.org/bar">
<include xmlns="http://example.org/include">
<fragment><foo:elem bar="tricky"/></fragment>
</include>
</root>
""")
target = libxml2.parseDoc("""<?xml version="1.0"?>
<root xmlns:foobar="http://example.org/bar"/>""")
fragment = source.xpathEval("//*[name()='fragment']")[0]
dest = target.getRootElement()
# do a cut and paste operation
fragment.unlinkNode()
dest.addChild(fragment)
# do the namespace fixup
dest.reconciliateNs(target)
# The source tree can be freed at that point
source.freeDoc()
# check the resulting tree
str = dest.serialize()
if str != """<root xmlns:foobar="http://example.org/bar" xmlns:default="http://example.org/include" xmlns:foo="http://example.org/foo"><default:fragment><foo:elem bar="tricky"/></default:fragment></root>""":
print("reconciliateNs() failed")
sys.exit(1)
target.freeDoc()
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/env python3
import setup_test
import libxml2
import sys
# Memory debug specific
libxml2.debugMemory(1)
dtd="""<!ELEMENT foo EMPTY>"""
instance="""<?xml version="1.0"?>
<foo></foo>"""
dtd = libxml2.parseDTD(None, 'test.dtd')
ctxt = libxml2.newValidCtxt()
doc = libxml2.parseDoc(instance)
ret = doc.validateDtd(ctxt, dtd)
if ret != 1:
print("error doing DTD validation")
sys.exit(1)
doc.freeDoc()
dtd.freeDtd()
del dtd
del ctxt
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/env python3
#
# This test exercise the redirection of error messages with a
# functions defined in Python.
#
import sys
import setup_test
import libxml2
# Memory debug specific
libxml2.debugMemory(1)
expect='--> I/O --> warning : --> failed to load "missing.xml": No such file or directory\n'
err=""
def callback(ctx, str):
global err
err = err + "%s %s" % (ctx, str)
got_exc = 0
libxml2.registerErrorHandler(callback, "-->")
try:
doc = libxml2.parseFile("missing.xml")
except libxml2.parserError:
got_exc = 1
if got_exc == 0:
print("Failed to get a parser exception")
sys.exit(1)
if err != expect:
print("error")
print("received %s" %(err))
print("expected %s" %(expect))
sys.exit(1)
i = 10000
while i > 0:
try:
doc = libxml2.parseFile("missing.xml")
except libxml2.parserError:
got_exc = 1
err = ""
i = i - 1
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+30
View File
@@ -0,0 +1,30 @@
#!/usr/bin/env python3
import sys
import setup_test
import libxml2
try:
import StringIO
str_io = StringIO.StringIO
except:
import io
str_io = io.StringIO
# Memory debug specific
libxml2.debugMemory(1)
i = 0
while i < 5000:
f = str_io("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)))
+113
View File
@@ -0,0 +1,113 @@
#!/usr/bin/env python3
# -*- coding: ISO-8859-1 -*-
import sys
import setup_test
import libxml2
# Memory debug specific
libxml2.debugMemory(1)
ctxt = None
class callback:
def __init__(self, startd, starte, ende, delta, endd):
self.startd = startd
self.starte = starte
self.ende = ende
self.endd = endd
self.delta = delta
self.count = 0
def startDocument(self):
global ctxt
if ctxt.byteConsumed() != self.startd:
print("document start at wrong index: %d expecting %d\n" % (
ctxt.byteConsumed(), self.startd))
sys.exit(1)
def endDocument(self):
global ctxt
expect = self.ende + self.delta * (self.count - 1) + self.endd
if ctxt.byteConsumed() != expect:
print("document end at wrong index: %d expecting %d\n" % (
ctxt.byteConsumed(), expect))
sys.exit(1)
def startElement(self, tag, attrs):
global ctxt
if tag == "bar1":
expect = self.starte + self.delta * self.count
if ctxt.byteConsumed() != expect:
print("element start at wrong index: %d expecting %d\n" % (
ctxt.byteConsumed(), expect))
sys.exit(1)
def endElement(self, tag):
global ctxt
if tag == "bar1":
expect = self.ende + self.delta * self.count
if ctxt.byteConsumed() != expect:
print("element end at wrong index: %d expecting %d\n" % (
ctxt.byteConsumed(), expect))
sys.exit(1)
self.count = self.count + 1
def characters(self, data):
pass
#
# First run a pure UTF-8 test
#
handler = callback(0, 13, 27, 198, 183)
ctxt = libxml2.createPushParser(handler, "<foo>\n", 6, "test.xml")
chunk = """ <bar1>chars1</bar1>
<bar2>chars2</bar2>
<bar3>chars3</bar3>
<bar4>chars4</bar4>
<bar5>chars5</bar5>
<bar6>&lt;s6</bar6>
<bar7>chars7</bar7>
<bar8>&#38;8</bar8>
<bar9>chars9</bar9>
"""
i = 0
while i < 10000:
ctxt.parseChunk(chunk, len(chunk), 0)
i = i + 1
chunk = "</foo>"
ctxt.parseChunk(chunk, len(chunk), 1)
ctxt=None
#
# Then run a test relying on ISO-Latin-1
#
handler = callback(43, 57, 71, 198, 183)
chunk="""<?xml version="1.0" encoding="ISO-8859-1"?>
<foo>
"""
ctxt = libxml2.createPushParser(handler, chunk, len(chunk), "test.xml")
chunk = """ <bar1>chars1</bar1>
<bar2>chars2</bar2>
<bar3>chars3</bar3>
<bar4>chàrs4</bar4>
<bar5>chars5</bar5>
<bar6>&lt;s6</bar6>
<bar7>chars7</bar7>
<bar8>&#38;8</bar8>
<bar9>très 9</bar9>
"""
i = 0
while i < 10000:
ctxt.parseChunk(chunk, len(chunk), 0)
i = i + 1
chunk = "</foo>"
ctxt.parseChunk(chunk, len(chunk), 1)
ctxt=None
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+149
View File
@@ -0,0 +1,149 @@
#!/usr/bin/env python3
#
# This tests custom input callbacks
#
import sys
import setup_test
import libxml2
try:
import StringIO
str_io = StringIO.StringIO
except:
import io
str_io = io.StringIO
# We implement a new scheme, py://strings/ that will reference this dictionary
pystrings = {
'catalogs/catalog.xml' :
'''<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE catalog PUBLIC "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN" "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<rewriteSystem systemIdStartString="http://example.com/dtds/" rewritePrefix="../dtds/"/>
</catalog>''',
'xml/sample.xml' :
'''<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root SYSTEM "http://example.com/dtds/sample.dtd">
<root>&sample.entity;</root>''',
'dtds/sample.dtd' :
'''
<!ELEMENT root (#PCDATA)>
<!ENTITY sample.entity "replacement text">'''
}
prefix = "py://strings/"
startURL = prefix + "xml/sample.xml"
catURL = prefix + "catalogs/catalog.xml"
def my_input_cb(URI):
if not(URI.startswith(prefix)):
return None
path = URI[len(prefix):]
if path not in pystrings:
return None
return str_io(pystrings[path])
def run_test(desc, docpath, catalog, exp_status="verified", exp_err=[], test_callback=None,
root_name="root", root_content="replacement text"):
opts = libxml2.XML_PARSE_DTDLOAD | libxml2.XML_PARSE_NONET | libxml2.XML_PARSE_COMPACT
actual_err = []
def my_global_error_cb(ctx, msg):
actual_err.append((-1, msg))
def my_ctx_error_cb(arg, msg, severity, reserved):
actual_err.append((severity, msg))
libxml2.registerErrorHandler(my_global_error_cb, None)
try:
parser = libxml2.createURLParserCtxt(docpath, opts)
parser.setErrorHandler(my_ctx_error_cb, None)
if catalog is not None:
parser.addLocalCatalog(catalog)
if test_callback is not None:
test_callback()
parser.parseDocument()
doc = parser.doc()
actual_status = "loaded"
e = doc.getRootElement()
if e.name == root_name and e.content == root_content:
actual_status = "verified"
doc.freeDoc()
except libxml2.parserError:
actual_status = "not loaded"
if actual_status != exp_status:
print("Test '%s' failed: expect status '%s', actual '%s'" % (desc, exp_status, actual_status))
sys.exit(1)
elif actual_err != exp_err:
print("Test '%s' failed" % desc)
print("Expect errors:")
for s,m in exp_err: print(" [%2d] '%s'" % (s,m))
print("Actual errors:")
for s,m in actual_err: print(" [%2d] '%s'" % (s,m))
sys.exit(1)
# Check that we cannot read custom schema without custom callback
run_test(desc="Loading entity without custom callback",
docpath=startURL, catalog=None,
exp_status="not loaded", exp_err=[
(-1, "I/O "),
(-1, "warning : "),
(-1, "failed to load \"py://strings/xml/sample.xml\": No such file or directory\n")
])
# Register handler and try to load the same entity
libxml2.registerInputCallback(my_input_cb)
run_test(desc="Loading entity with custom callback",
docpath=startURL, catalog=None,
exp_status="loaded", exp_err=[
( 4, 'failed to load "http://example.com/dtds/sample.dtd": Attempt to load network entity\n'),
( 4, "Entity 'sample.entity' not defined\n")
])
# Register a catalog (also accessible via pystr://) and retry
run_test(desc="Loading entity with custom callback and catalog",
docpath=startURL, catalog=catURL)
# Unregister custom callback when parser is already created
run_test(desc="Loading entity and unregistering callback",
docpath=startURL, catalog=catURL,
test_callback=lambda: libxml2.popInputCallbacks(),
exp_status="loaded", exp_err=[
( 3, "failed to load \"py://strings/dtds/sample.dtd\": No such file or directory\n"),
( 4, "Entity 'sample.entity' not defined\n")
])
# Try to load the document again
run_test(desc="Retry loading document after unregistering callback",
docpath=startURL, catalog=catURL,
exp_status="not loaded", exp_err=[
(-1, "I/O "),
(-1, "warning : "),
(-1, "failed to load \"py://strings/xml/sample.xml\": No such file or directory\n")
])
# But should be able to read standard I/O yet...
run_test(desc="Loading using standard i/o after unregistering callback",
docpath="tst.xml", catalog=None,
root_name='doc', root_content='bar')
# Now pop ALL input callbacks, should fail to load even standard I/O
try:
while True:
libxml2.popInputCallbacks()
except IndexError:
pass
run_test(desc="Loading using standard i/o after unregistering all callbacks",
docpath="tst.xml", catalog=None,
exp_status="not loaded", exp_err=[
(-1, "I/O "),
(-1, "warning : "),
(-1, "failed to load \"tst.xml\": No such file or directory\n")
])
print("OK")
sys.exit(0);
+6
View File
@@ -0,0 +1,6 @@
<!DOCTYPE doc [
<!ELEMENT doc (a, b, a)>
<!ELEMENT a EMPTY>
<!ELEMENT b EMPTY>
]>
<doc><b/><a/><b/></doc>
+62
View File
@@ -0,0 +1,62 @@
#!/usr/bin/env python3
#
# this test exercise the XPath basic engine, parser, etc, and
# allows to detect memory leaks
#
import sys
import setup_test
import libxml2
instance="""<?xml version="1.0"?>
<tag xmlns:foo='urn:foo' xmlns:bar='urn:bar' xmlns:baz='urn:baz' />"""
def namespaceDefs(node):
n = node.nsDefs()
while n:
yield n
n = n.next
def checkNamespaceDefs(node, count):
nsList = list(namespaceDefs(node))
#print nsList
if len(nsList) != count :
raise Exception("Error: saw %d namespace declarations. Expected %d" % (len(nsList), count))
# Memory debug specific
libxml2.debugMemory(1)
# Remove single namespace
doc = libxml2.parseDoc(instance)
node = doc.getRootElement()
checkNamespaceDefs(node, 3)
ns = node.removeNsDef('urn:bar')
checkNamespaceDefs(node, 2)
ns.freeNsList()
doc.freeDoc()
# Remove all namespaces
doc = libxml2.parseDoc(instance)
node = doc.getRootElement()
checkNamespaceDefs(node, 3)
ns = node.removeNsDef(None)
checkNamespaceDefs(node, 0)
ns.freeNsList()
doc.freeDoc()
# Remove a namespace referred to by a child
doc = libxml2.newDoc("1.0")
root = doc.newChild(None, "root", None)
namespace = root.newNs("http://example.com/sample", "s")
child = root.newChild(namespace, "child", None)
root.removeNsDef("http://example.com/sample")
doc.reconciliateNs(root)
namespace.freeNsList()
doc.serialize() # This should not segfault
doc.freeDoc()
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+110
View File
@@ -0,0 +1,110 @@
#!/usr/bin/env python3
import sys
import setup_test
import libxml2
try:
import StringIO
str_io = StringIO.StringIO
except:
import io
str_io = io.StringIO
def testSimpleBufferWrites():
f = str_io()
buf = libxml2.createOutputBuffer(f, "ISO-8859-1")
buf.write(3, "foo")
buf.writeString("bar")
buf.close()
if f.getvalue() != "foobar":
print("Failed to save to StringIO")
sys.exit(1)
def testSaveDocToBuffer():
"""
Regression test for bug #154294.
"""
input = '<foo>Hello</foo>'
expected = '''\
<?xml version="1.0" encoding="UTF-8"?>
<foo>Hello</foo>
'''
f = str_io()
buf = libxml2.createOutputBuffer(f, 'UTF-8')
doc = libxml2.parseDoc(input)
doc.saveFileTo(buf, 'UTF-8')
doc.freeDoc()
if f.getvalue() != expected:
print('xmlDoc.saveFileTo() call failed.')
print(' got: %s' % repr(f.getvalue()))
print('expected: %s' % repr(expected))
sys.exit(1)
def testSaveFormattedDocToBuffer():
input = '<outer><inner>Some text</inner><inner/></outer>'
# The formatted and non-formatted versions of the output.
expected = ('''\
<?xml version="1.0" encoding="UTF-8"?>
<outer><inner>Some text</inner><inner/></outer>
''', '''\
<?xml version="1.0" encoding="UTF-8"?>
<outer>
<inner>Some text</inner>
<inner/>
</outer>
''')
doc = libxml2.parseDoc(input)
for i in (0, 1):
f = str_io()
buf = libxml2.createOutputBuffer(f, 'UTF-8')
doc.saveFormatFileTo(buf, 'UTF-8', i)
if f.getvalue() != expected[i]:
print('xmlDoc.saveFormatFileTo() call failed.')
print(' got: %s' % repr(f.getvalue()))
print('expected: %s' % repr(expected[i]))
sys.exit(1)
doc.freeDoc()
def testSaveIntoOutputBuffer():
"""
Similar to the previous two tests, except this time we invoke the save
methods on the output buffer object and pass in an XML node object.
"""
input = '<foo>Hello</foo>'
expected = '''\
<?xml version="1.0" encoding="UTF-8"?>
<foo>Hello</foo>
'''
f = str_io()
doc = libxml2.parseDoc(input)
buf = libxml2.createOutputBuffer(f, 'UTF-8')
buf.saveFileTo(doc, 'UTF-8')
if f.getvalue() != expected:
print('outputBuffer.saveFileTo() call failed.')
print(' got: %s' % repr(f.getvalue()))
print('expected: %s' % repr(expected))
sys.exit(1)
f = str_io()
buf = libxml2.createOutputBuffer(f, 'UTF-8')
buf.saveFormatFileTo(doc, 'UTF-8', 1)
if f.getvalue() != expected:
print('outputBuffer.saveFormatFileTo() call failed.')
print(' got: %s' % repr(f.getvalue()))
print('expected: %s' % repr(expected))
sys.exit(1)
doc.freeDoc()
if __name__ == '__main__':
# Memory debug specific
libxml2.debugMemory(1)
testSimpleBufferWrites()
testSaveDocToBuffer()
testSaveFormattedDocToBuffer()
testSaveIntoOutputBuffer()
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+35
View File
@@ -0,0 +1,35 @@
#!/usr/bin/env python3
import sys
import setup_test
import libxml2
# Memory debug specific
libxml2.debugMemory(1)
ctxt = libxml2.createPushParser(None, "<foo", 4, "test.xml")
ctxt.parseChunk("/>", 2, 1)
doc = ctxt.doc()
ctxt=None
if doc.name != "test.xml":
print("document name error")
sys.exit(1)
root = doc.children
if root.name != "foo":
print("root element name error")
sys.exit(1)
doc.freeDoc()
i = 10000
while i > 0:
ctxt = libxml2.createPushParser(None, "<foo", 4, "test.xml")
ctxt.parseChunk("/>", 2, 1)
doc = ctxt.doc()
doc.freeDoc()
i = i -1
ctxt=None
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+64
View File
@@ -0,0 +1,64 @@
#!/usr/bin/env python3
import sys
import setup_test
import libxml2
# Memory debug specific
libxml2.debugMemory(1)
log = ""
class callback:
def startDocument(self):
global log
log = log + "startDocument:"
def endDocument(self):
global log
log = log + "endDocument:"
def startElement(self, tag, attrs):
global log
log = log + "startElement %s %s:" % (tag, attrs)
def endElement(self, tag):
global log
log = log + "endElement %s:" % (tag)
def characters(self, data):
global log
log = log + "characters: %s:" % (data)
def warning(self, msg):
global log
log = log + "warning: %s:" % (msg)
def error(self, msg):
global log
log = log + "error: %s:" % (msg)
def fatalError(self, msg):
global log
log = log + "fatalError: %s:" % (msg)
handler = callback()
ctxt = libxml2.createPushParser(handler, "<foo", 4, "test.xml")
chunk = " url='tst'>b"
ctxt.parseChunk(chunk, len(chunk), 0)
chunk = "ar</foo>"
ctxt.parseChunk(chunk, len(chunk), 1)
ctxt=None
reference = "startDocument:startElement foo {'url': 'tst'}:characters: bar:endElement foo:endDocument:"
if log != reference:
print("Error got: %s" % log)
print("Exprected: %s" % reference)
sys.exit(1)
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+64
View File
@@ -0,0 +1,64 @@
#!/usr/bin/env python3
import sys
import setup_test
import libxml2
# Memory debug specific
libxml2.debugMemory(1)
log = ""
class callback:
def startDocument(self):
global log
log = log + "startDocument:"
def endDocument(self):
global log
log = log + "endDocument:"
def startElement(self, tag, attrs):
global log
log = log + "startElement %s %s:" % (tag, attrs)
def endElement(self, tag):
global log
log = log + "endElement %s:" % (tag)
def characters(self, data):
global log
log = log + "characters: %s:" % (data)
def warning(self, msg):
global log
log = log + "warning: %s:" % (msg)
def error(self, msg):
global log
log = log + "error: %s:" % (msg)
def fatalError(self, msg):
global log
log = log + "fatalError: %s:" % (msg)
handler = callback()
ctxt = libxml2.htmlCreatePushParser(handler, "<foo", 4, "test.xml")
chunk = " url='tst'>b"
ctxt.htmlParseChunk(chunk, len(chunk), 0)
chunk = "ar</foo>"
ctxt.htmlParseChunk(chunk, len(chunk), 1)
ctxt=None
reference = """startDocument:startElement html None:startElement body None:startElement foo {'url': 'tst'}:characters: bar:endElement foo:endElement body:endElement html:endDocument:"""
if log != reference:
print("Error got: %s" % log)
print("Exprected: %s" % reference)
sys.exit(1)
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+446
View File
@@ -0,0 +1,446 @@
#!/usr/bin/env python3
# -*- coding: ISO-8859-1 -*-
#
# this tests the basic APIs of the XmlTextReader interface
#
import setup_test
import libxml2
import sys
try:
import StringIO
str_io = StringIO.StringIO
except:
import io
str_io = io.StringIO
# Memory debug specific
libxml2.debugMemory(1)
f = str_io("""<a><b b1="b1"/><c>content of c</c></a>""")
input = libxml2.inputBuffer(f)
reader = input.newTextReader("test1")
ret = reader.Read()
if ret != 1:
print("test1: 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("test1: Error reading the first element")
sys.exit(1)
ret = reader.Read()
if ret != 1:
print("test1: 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("test1: Error reading the second element")
sys.exit(1)
ret = reader.Read()
if ret != 1:
print("test1: 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("test1: Error reading the third element")
sys.exit(1)
ret = reader.Read()
if ret != 1:
print("test1: 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("test1: Error reading the text node")
sys.exit(1)
ret = reader.Read()
if ret != 1:
print("test1: 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("test1: Error reading the end of third element")
sys.exit(1)
ret = reader.Read()
if ret != 1:
print("test1: 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("test1: Error reading the end of first element")
sys.exit(1)
ret = reader.Read()
if ret != 0:
print("test1: Error reading to end of document")
sys.exit(1)
#
# example from the XmlTextReader docs
#
f = str_io("""<test xmlns:dt="urn:datatypes" dt:type="int"/>""")
input = libxml2.inputBuffer(f)
reader = input.newTextReader("test2")
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)
#
# example from the XmlTextReader docs
#
f = str_io("""<root xmlns:a="urn:456">
<item>
<ref href="a:b"/>
</item>
</root>""")
input = libxml2.inputBuffer(f)
reader = input.newTextReader("test3")
ret = reader.Read()
while ret == 1:
if reader.Name() == "ref":
if reader.LookupNamespace("a") != "urn:456":
print("error resolving namespace prefix")
sys.exit(1)
break
ret = reader.Read()
if ret != 1:
print("Error finding the ref element")
sys.exit(1)
#
# Home made example for the various attribute access functions
#
f = str_io("""<testattr xmlns="urn:1" xmlns:a="urn:2" b="b" a:b="a:b"/>""")
input = libxml2.inputBuffer(f)
reader = input.newTextReader("test4")
ret = reader.Read()
if ret != 1:
print("Error reading the testattr element")
sys.exit(1)
#
# Attribute exploration by index
#
if reader.MoveToAttributeNo(0) != 1:
print("Failed moveToAttribute(0)")
sys.exit(1)
if reader.Value() != "urn:1":
print("Failed to read attribute(0)")
sys.exit(1)
if reader.Name() != "xmlns":
print("Failed to read attribute(0) name")
sys.exit(1)
if reader.MoveToAttributeNo(1) != 1:
print("Failed moveToAttribute(1)")
sys.exit(1)
if reader.Value() != "urn:2":
print("Failed to read attribute(1)")
sys.exit(1)
if reader.Name() != "xmlns:a":
print("Failed to read attribute(1) name")
sys.exit(1)
if reader.MoveToAttributeNo(2) != 1:
print("Failed moveToAttribute(2)")
sys.exit(1)
if reader.Value() != "b":
print("Failed to read attribute(2)")
sys.exit(1)
if reader.Name() != "b":
print("Failed to read attribute(2) name")
sys.exit(1)
if reader.MoveToAttributeNo(3) != 1:
print("Failed moveToAttribute(3)")
sys.exit(1)
if reader.Value() != "a:b":
print("Failed to read attribute(3)")
sys.exit(1)
if reader.Name() != "a:b":
print("Failed to read attribute(3) name")
sys.exit(1)
#
# Attribute exploration by name
#
if reader.MoveToAttribute("xmlns") != 1:
print("Failed moveToAttribute('xmlns')")
sys.exit(1)
if reader.Value() != "urn:1":
print("Failed to read attribute('xmlns')")
sys.exit(1)
if reader.MoveToAttribute("xmlns:a") != 1:
print("Failed moveToAttribute('xmlns')")
sys.exit(1)
if reader.Value() != "urn:2":
print("Failed to read attribute('xmlns:a')")
sys.exit(1)
if reader.MoveToAttribute("b") != 1:
print("Failed moveToAttribute('b')")
sys.exit(1)
if reader.Value() != "b":
print("Failed to read attribute('b')")
sys.exit(1)
if reader.MoveToAttribute("a:b") != 1:
print("Failed moveToAttribute('a:b')")
sys.exit(1)
if reader.Value() != "a:b":
print("Failed to read attribute('a:b')")
sys.exit(1)
if reader.MoveToAttributeNs("b", "urn:2") != 1:
print("Failed moveToAttribute('b', 'urn:2')")
sys.exit(1)
if reader.Value() != "a:b":
print("Failed to read attribute('b', 'urn:2')")
sys.exit(1)
#
# Go back and read in sequence
#
if reader.MoveToElement() != 1:
print("Failed to move back to element")
sys.exit(1)
if reader.MoveToFirstAttribute() != 1:
print("Failed to move to first attribute")
sys.exit(1)
if reader.Value() != "urn:1":
print("Failed to read attribute(0)")
sys.exit(1)
if reader.Name() != "xmlns":
print("Failed to read attribute(0) name")
sys.exit(1)
if reader.MoveToNextAttribute() != 1:
print("Failed to move to next attribute")
sys.exit(1)
if reader.Value() != "urn:2":
print("Failed to read attribute(1)")
sys.exit(1)
if reader.Name() != "xmlns:a":
print("Failed to read attribute(1) name")
sys.exit(1)
if reader.MoveToNextAttribute() != 1:
print("Failed to move to next attribute")
sys.exit(1)
if reader.Value() != "b":
print("Failed to read attribute(2)")
sys.exit(1)
if reader.Name() != "b":
print("Failed to read attribute(2) name")
sys.exit(1)
if reader.MoveToNextAttribute() != 1:
print("Failed to move to next attribute")
sys.exit(1)
if reader.Value() != "a:b":
print("Failed to read attribute(3)")
sys.exit(1)
if reader.Name() != "a:b":
print("Failed to read attribute(3) name")
sys.exit(1)
if reader.MoveToNextAttribute() != 0:
print("Failed to detect last attribute")
sys.exit(1)
#
# a couple of tests for namespace nodes
#
f = str_io("""<a xmlns="http://example.com/foo"/>""")
input = libxml2.inputBuffer(f)
reader = input.newTextReader("test6")
ret = reader.Read()
if ret != 1:
print("test6: failed to Read()")
sys.exit(1)
ret = reader.MoveToFirstAttribute()
if ret != 1:
print("test6: failed to MoveToFirstAttribute()")
sys.exit(1)
if reader.NamespaceUri() != "http://www.w3.org/2000/xmlns/" or \
reader.LocalName() != "xmlns" or reader.Name() != "xmlns" or \
reader.Value() != "http://example.com/foo" or reader.NodeType() != 2:
print("test6: failed to read the namespace node")
sys.exit(1)
f = str_io("""<a xmlns:prefix="http://example.com/foo"/>""")
input = libxml2.inputBuffer(f)
reader = input.newTextReader("test7")
ret = reader.Read()
if ret != 1:
print("test7: failed to Read()")
sys.exit(1)
ret = reader.MoveToFirstAttribute()
if ret != 1:
print("test7: failed to MoveToFirstAttribute()")
sys.exit(1)
if reader.NamespaceUri() != "http://www.w3.org/2000/xmlns/" or \
reader.LocalName() != "prefix" or reader.Name() != "xmlns:prefix" or \
reader.Value() != "http://example.com/foo" or reader.NodeType() != 2:
print("test7: failed to read the namespace node")
sys.exit(1)
#
# Test for a limit case:
#
f = str_io("""<a/>""")
input = libxml2.inputBuffer(f)
reader = input.newTextReader("test8")
ret = reader.Read()
if ret != 1:
print("test8: failed to read the node")
sys.exit(1)
if reader.Name() != "a" or reader.IsEmptyElement() != 1:
print("test8: failed to analyze the node")
sys.exit(1)
ret = reader.Read()
if ret != 0:
print("test8: failed to detect the EOF")
sys.exit(1)
#
# Another test provided by Stéphane Bidoul and checked with C#
#
def tst_reader(s):
f = str_io(s)
input = libxml2.inputBuffer(f)
reader = input.newTextReader("tst")
res = ""
while reader.Read():
res=res + "%s (%s) [%s] %d %d\n" % (reader.NodeType(),reader.Name(),
reader.Value(), reader.IsEmptyElement(),
reader.Depth())
if reader.NodeType() == 1: # Element
while reader.MoveToNextAttribute():
res = res + "-- %s (%s) [%s] %d %d\n" % (reader.NodeType(),
reader.Name(),reader.Value(),
reader.IsEmptyElement(), reader.Depth())
return res
doc="""<a><b b1="b1"/><c>content of c</c></a>"""
expect="""1 (a) [None] 0 0
1 (b) [None] 1 1
-- 2 (b1) [b1] 0 2
1 (c) [None] 0 1
3 (#text) [content of c] 0 2
15 (c) [None] 0 1
15 (a) [None] 0 0
"""
res = tst_reader(doc)
if res != expect:
print("test5 failed")
print(res)
sys.exit(1)
doc="""<test><b/><c/></test>"""
expect="""1 (test) [None] 0 0
1 (b) [None] 1 1
1 (c) [None] 1 1
15 (test) [None] 0 0
"""
res = tst_reader(doc)
if res != expect:
print("test9 failed")
print(res)
sys.exit(1)
doc="""<a><b>bbb</b><c>ccc</c></a>"""
expect="""1 (a) [None] 0 0
1 (b) [None] 0 1
3 (#text) [bbb] 0 2
15 (b) [None] 0 1
1 (c) [None] 0 1
3 (#text) [ccc] 0 2
15 (c) [None] 0 1
15 (a) [None] 0 0
"""
res = tst_reader(doc)
if res != expect:
print("test10 failed")
print(res)
sys.exit(1)
doc="""<test a="a"/>"""
expect="""1 (test) [None] 1 0
-- 2 (a) [a] 0 1
"""
res = tst_reader(doc)
if res != expect:
print("test11 failed")
print(res)
sys.exit(1)
doc="""<test><a>aaa</a><b/></test>"""
expect="""1 (test) [None] 0 0
1 (a) [None] 0 1
3 (#text) [aaa] 0 2
15 (a) [None] 0 1
1 (b) [None] 1 1
15 (test) [None] 0 0
"""
res = tst_reader(doc)
if res != expect:
print("test12 failed")
print(res)
sys.exit(1)
doc="""<test><p></p></test>"""
expect="""1 (test) [None] 0 0
1 (p) [None] 0 1
15 (p) [None] 0 1
15 (test) [None] 0 0
"""
res = tst_reader(doc)
if res != expect:
print("test13 failed")
print(res)
sys.exit(1)
doc="""<p></p>"""
expect="""1 (p) [None] 0 0
15 (p) [None] 0 0
"""
res = tst_reader(doc)
if res != expect:
print("test14 failed")
print(res)
sys.exit(1)
#
# test from bug #108801
#
doc="""<?xml version="1.0" standalone="no"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
]>
<article>
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
</article>
"""
expect="""10 (article) [None] 0 0
1 (article) [None] 0 0
3 (#text) [
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
] 0 1
15 (article) [None] 0 0
"""
res = tst_reader(doc)
if res != expect:
print("test15 failed")
print(res)
sys.exit(1)
#
# cleanup for memory allocation counting
#
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)))
+337
View File
@@ -0,0 +1,337 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# this tests the DTD validation with the XmlTextReader interface
#
import sys
import glob
import os
import setup_test
import libxml2
try:
import StringIO
str_io = StringIO.StringIO
except:
import io
str_io = io.StringIO
# Memory debug specific
libxml2.debugMemory(1)
err = ""
basedir = os.path.dirname(os.path.realpath(__file__))
dir_prefix = os.path.realpath(os.path.join(basedir, "..", "..", "test", "valid"))
# This dictionary reflects the contents of the files
# ../../test/valid/*.xml.err that are not empty, except that
# the file paths in the messages start with ../../test/
expect = {
'766956':
"""{0}/dtds/766956.dtd:2: parser error : PEReference: expecting ';'
%ä%ent;
^
{0}/dtds/766956.dtd:2: parser error : Content error in the external subset
%ä%ent;
^
Entity: line 1:
value
^
""".format(dir_prefix),
'781333':
"""{0}/781333.xml:4: element a: validity error : Element a content does not follow the DTD, expecting ( ..., got
<a/>
^
{0}/781333.xml:5: element a: validity error : Element a content does not follow the DTD, Expecting more children
^
""".format(dir_prefix),
'cond_sect2':
"""{0}/dtds/cond_sect2.dtd:15: parser error : Parameter entity must match extSubsetDecl
%ent;
^
Entity: line 1:
]]>
^
{0}/dtds/cond_sect2.dtd:15: parser error : Content error in the external subset
%ent;
^
Entity: line 1:
]]>
^
""".format(dir_prefix),
'rss':
"""{0}/rss.xml:177: element rss: validity error : Element rss does not carry attribute version
</rss>
^
""".format(dir_prefix),
't8':
"""{0}/t8.xml:6: parser error : Content error in the internal subset
%defroot; %defmiddle; %deftest;
^
Entity: line 1:
&lt;!ELEMENT root (middle) >
^
""".format(dir_prefix),
't8a':
"""{0}/t8a.xml:6: parser error : Content error in the internal subset
%defroot;%defmiddle;%deftest;
^
Entity: line 1:
&lt;!ELEMENT root (middle) >
^
""".format(dir_prefix),
'xlink':
"""{0}/xlink.xml:450: element termdef: validity error : ID dt-arc already defined
<p><termdef id="dt-arc" term="Arc">An <ter
^
validity error : attribute def line 199 references an unknown ID "dt-xlg"
""".format(dir_prefix),
}
# Add prefix_dir and extension to the keys
expect = {os.path.join(dir_prefix, key + ".xml"): val for key, val in expect.items()}
def callback(ctx, str):
global err
err = err + "%s" % (str)
libxml2.registerErrorHandler(callback, "")
parsing_error_files = ["766956", "cond_sect2", "t8", "t8a", "pe-in-text-decl"]
expect_parsing_error = [os.path.join(dir_prefix, f + ".xml") for f in parsing_error_files]
valid_files = glob.glob(os.path.join(dir_prefix, "*.x*"))
assert valid_files, "found no valid files in '{}'".format(dir_prefix)
valid_files.sort()
failures = 0
for file in valid_files:
err = ""
reader = libxml2.newTextReaderFilename(file)
#print "%s:" % (file)
reader.SetParserProp(libxml2.PARSER_VALIDATE, 1)
ret = reader.Read()
while ret == 1:
ret = reader.Read()
if ret != 0 and file not in expect_parsing_error:
print("Error parsing and validating %s" % (file))
#sys.exit(1)
if file in expect and err != expect[file]:
failures += 1
print("Error: ", err)
if file in expect:
print("Expected: ", expect[file])
if failures:
print("Failed %d tests" % failures)
sys.exit(1)
#
# another separate test based on Stephane Bidoul one
#
s = """
<!DOCTYPE test [
<!ELEMENT test (x,b)>
<!ELEMENT x (c)>
<!ELEMENT b (#PCDATA)>
<!ELEMENT c (#PCDATA)>
<!ENTITY x "<x><c>xxx</c></x>">
]>
<test>
&x;
<b>bbb</b>
</test>
"""
expect="""10,test
1,test
14,#text
1,x
1,c
3,#text
15,c
15,x
14,#text
1,b
3,#text
15,b
14,#text
15,test
"""
res=""
err=""
input = libxml2.inputBuffer(str_io(s))
reader = input.newTextReader("test2")
reader.SetParserProp(libxml2.PARSER_LOADDTD,1)
reader.SetParserProp(libxml2.PARSER_DEFAULTATTRS,1)
reader.SetParserProp(libxml2.PARSER_SUBST_ENTITIES,1)
reader.SetParserProp(libxml2.PARSER_VALIDATE,1)
while reader.Read() == 1:
res = res + "%s,%s\n" % (reader.NodeType(),reader.Name())
if res != expect:
print("test2 failed: unexpected output")
print(res)
sys.exit(1)
if err != "":
print("test2 failed: validation error found")
print(err)
sys.exit(1)
#
# Another test for external entity parsing and validation
#
s = """<!DOCTYPE test [
<!ELEMENT test (x)>
<!ELEMENT x (#PCDATA)>
<!ENTITY e SYSTEM "tst.ent">
]>
<test>
&e;
</test>
"""
tst_ent = """<x>hello</x>"""
expect="""10 test
1 test
14 #text
1 x
3 #text
15 x
14 #text
15 test
"""
res=""
def myResolver(URL, ID, ctxt):
if URL == "tst.ent":
return(str_io(tst_ent))
return None
libxml2.setEntityLoader(myResolver)
input = libxml2.inputBuffer(str_io(s))
reader = input.newTextReader("test3")
reader.SetParserProp(libxml2.PARSER_LOADDTD,1)
reader.SetParserProp(libxml2.PARSER_DEFAULTATTRS,1)
reader.SetParserProp(libxml2.PARSER_SUBST_ENTITIES,1)
reader.SetParserProp(libxml2.PARSER_VALIDATE,1)
while reader.Read() == 1:
res = res + "%s %s\n" % (reader.NodeType(),reader.Name())
if res != expect:
print("test3 failed: unexpected output")
print(res)
sys.exit(1)
if err != "":
print("test3 failed: validation error found")
print(err)
sys.exit(1)
#
# Another test for recursive entity parsing, validation, and replacement of
# entities, making sure the entity ref node doesn't show up in that case
#
s = """<!DOCTYPE test [
<!ELEMENT test (x, x)>
<!ELEMENT x (y)>
<!ELEMENT y (#PCDATA)>
<!ENTITY x "<x>&y;</x>">
<!ENTITY y "<y>yyy</y>">
]>
<test>
&x;
&x;
</test>"""
expect="""10 test 0
1 test 0
14 #text 1
1 x 1
1 y 2
3 #text 3
15 y 2
15 x 1
14 #text 1
1 x 1
1 y 2
3 #text 3
15 y 2
15 x 1
14 #text 1
15 test 0
"""
res=""
err=""
input = libxml2.inputBuffer(str_io(s))
reader = input.newTextReader("test4")
reader.SetParserProp(libxml2.PARSER_LOADDTD,1)
reader.SetParserProp(libxml2.PARSER_DEFAULTATTRS,1)
reader.SetParserProp(libxml2.PARSER_SUBST_ENTITIES,1)
reader.SetParserProp(libxml2.PARSER_VALIDATE,1)
while reader.Read() == 1:
res = res + "%s %s %d\n" % (reader.NodeType(),reader.Name(),reader.Depth())
if res != expect:
print("test4 failed: unexpected output")
print(res)
sys.exit(1)
if err != "":
print("test4 failed: validation error found")
print(err)
sys.exit(1)
#
# The same test but without entity substitution this time
#
s = """<!DOCTYPE test [
<!ELEMENT test (x, x)>
<!ELEMENT x (y)>
<!ELEMENT y (#PCDATA)>
<!ENTITY x "<x>&y;</x>">
<!ENTITY y "<y>yyy</y>">
]>
<test>
&x;
&x;
</test>"""
expect="""10 test 0
1 test 0
14 #text 1
5 x 1
14 #text 1
5 x 1
14 #text 1
15 test 0
"""
res=""
err=""
input = libxml2.inputBuffer(str_io(s))
reader = input.newTextReader("test5")
reader.SetParserProp(libxml2.PARSER_VALIDATE,1)
while reader.Read() == 1:
res = res + "%s %s %d\n" % (reader.NodeType(),reader.Name(),reader.Depth())
if res != expect:
print("test5 failed: unexpected output")
print(res)
sys.exit(1)
if err != "":
print("test5 failed: validation error found")
print(err)
sys.exit(1)
#
# cleanup
#
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)))
+160
View File
@@ -0,0 +1,160 @@
#!/usr/bin/env python3
#
# this tests the entities substitutions with the XmlTextReader interface
#
import sys
import setup_test
import libxml2
try:
import StringIO
str_io = StringIO.StringIO
except:
import io
str_io = io.StringIO
docstr="""<?xml version='1.0'?>
<!DOCTYPE doc [
<!ENTITY tst "<p>test</p>">
]>
<doc>&tst;</doc>"""
# Memory debug specific
libxml2.debugMemory(1)
#
# First test, normal don't substitute entities.
#
f = str_io(docstr)
input = libxml2.inputBuffer(f)
reader = input.newTextReader("test_noent")
ret = reader.Read()
if ret != 1:
print("Error reading to root")
sys.exit(1)
if reader.Name() == "doc" or reader.NodeType() == 10:
ret = reader.Read()
if ret != 1:
print("Error reading to root")
sys.exit(1)
if reader.Name() != "doc" or reader.NodeType() != 1:
print("test_normal: Error reading the root element")
sys.exit(1)
ret = reader.Read()
if ret != 1:
print("test_normal: Error reading to the entity")
sys.exit(1)
if reader.Name() != "tst" or reader.NodeType() != 5:
print("test_normal: Error reading the entity")
sys.exit(1)
ret = reader.Read()
if ret != 1:
print("test_normal: Error reading to the end of root")
sys.exit(1)
if reader.Name() != "doc" or reader.NodeType() != 15:
print("test_normal: Error reading the end of the root element")
sys.exit(1)
ret = reader.Read()
if ret != 0:
print("test_normal: Error detecting the end")
sys.exit(1)
#
# Second test, completely substitute the entities.
#
f = str_io(docstr)
input = libxml2.inputBuffer(f)
reader = input.newTextReader("test_noent")
reader.SetParserProp(libxml2.PARSER_SUBST_ENTITIES, 1)
ret = reader.Read()
if ret != 1:
print("Error reading to root")
sys.exit(1)
if reader.Name() == "doc" or reader.NodeType() == 10:
ret = reader.Read()
if ret != 1:
print("Error reading to root")
sys.exit(1)
if reader.Name() != "doc" or reader.NodeType() != 1:
print("test_noent: Error reading the root element")
sys.exit(1)
ret = reader.Read()
if ret != 1:
print("test_noent: Error reading to the entity content")
sys.exit(1)
if reader.Name() != "p" or reader.NodeType() != 1:
print("test_noent: Error reading the p element from entity")
sys.exit(1)
ret = reader.Read()
if ret != 1:
print("test_noent: Error reading to the text node")
sys.exit(1)
if reader.NodeType() != 3 or reader.Value() != "test":
print("test_noent: Error reading the text node")
sys.exit(1)
ret = reader.Read()
if ret != 1:
print("test_noent: Error reading to the end of p element")
sys.exit(1)
if reader.Name() != "p" or reader.NodeType() != 15:
print("test_noent: Error reading the end of the p element")
sys.exit(1)
ret = reader.Read()
if ret != 1:
print("test_noent: Error reading to the end of root")
sys.exit(1)
if reader.Name() != "doc" or reader.NodeType() != 15:
print("test_noent: Error reading the end of the root element")
sys.exit(1)
ret = reader.Read()
if ret != 0:
print("test_noent: Error detecting the end")
sys.exit(1)
#
# third test, crazy stuff about empty element in external parsed entities
#
s = """<!DOCTYPE struct [
<!ENTITY simplestruct2.ent SYSTEM "simplestruct2.ent">
]>
<struct>&simplestruct2.ent;</struct>
"""
expect="""10 struct 0 0
1 struct 0 0
1 descr 1 1
15 struct 0 0
"""
res=""
simplestruct2_ent="""<descr/>"""
def myResolver(URL, ID, ctxt):
if URL == "simplestruct2.ent":
return(str_io(simplestruct2_ent))
return None
libxml2.setEntityLoader(myResolver)
input = libxml2.inputBuffer(str_io(s))
reader = input.newTextReader("test3")
reader.SetParserProp(libxml2.PARSER_SUBST_ENTITIES,1)
while reader.Read() == 1:
res = res + "%s %s %d %d\n" % (reader.NodeType(),reader.Name(),
reader.Depth(),reader.IsEmptyElement())
if res != expect:
print("test3 failed: unexpected output")
print(res)
sys.exit(1)
#
# cleanup
#
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)))
+50
View File
@@ -0,0 +1,50 @@
#!/usr/bin/env python3
#
# this tests the basic APIs of the XmlTextReader interface
#
import setup_test
import libxml2
import sys
try:
import StringIO
str_io = StringIO.StringIO
except:
import io
str_io = io.StringIO
# Memory debug specific
libxml2.debugMemory(1)
def tst_reader(s):
f = str_io(s)
input = libxml2.inputBuffer(f)
reader = input.newTextReader("tst")
res = ""
while reader.Read():
res=res + "%s (%s) [%s] %d\n" % (reader.NodeType(),reader.Name(),
reader.Value(), reader.IsEmptyElement())
if reader.NodeType() == 1: # Element
while reader.MoveToNextAttribute():
res = res + "-- %s (%s) [%s]\n" % (reader.NodeType(),
reader.Name(),reader.Value())
return res
expect="""1 (test) [None] 0
1 (b) [None] 1
1 (c) [None] 1
15 (test) [None] 0
"""
res = tst_reader("""<test><b/><c/></test>""")
if res != expect:
print("Did not get the expected error message:")
print(res)
sys.exit(1)
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+49
View File
@@ -0,0 +1,49 @@
#!/usr/bin/env python3
#
# this tests the Expand() API of the xmlTextReader interface
# this extract the Dragon bibliography entries from the XML specification
#
import setup_test
import libxml2
import os
import sys
# Memory debug specific
libxml2.debugMemory(1)
expect="""<bibl id="Aho" key="Aho/Ullman">Aho, Alfred V.,
Ravi Sethi, and Jeffrey D. Ullman.
<emph>Compilers: Principles, Techniques, and Tools</emph>.
Reading: Addison-Wesley, 1986, rpt. corr. 1988.</bibl>"""
basedir = os.path.dirname(os.path.realpath(__file__))
f = open(os.path.join(basedir, '../../test/valid/REC-xml-19980210.xml'), 'rb')
input = libxml2.inputBuffer(f)
reader = input.newTextReader("REC")
res=""
while reader.Read() > 0:
while reader.Name() == 'bibl':
node = reader.Expand() # expand the subtree
if node.xpathEval("@id = 'Aho'"): # use XPath on it
res = res + node.serialize()
if reader.Next() != 1: # skip the subtree
break;
if res != expect:
print("Error: didn't get the expected output")
print("got '%s'" % (res))
print("expected '%s'" % (expect))
#
# cleanup
#
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)))
+128
View File
@@ -0,0 +1,128 @@
#!/usr/bin/env python3
#
# this tests the entities substitutions with the XmlTextReader interface
#
import sys
import setup_test
import libxml2
try:
import StringIO
str_io = StringIO.StringIO
except:
import io
str_io = io.StringIO
schema="""<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0"
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
<oneOrMore>
<element name="label">
<text/>
</element>
<optional>
<element name="opt">
<empty/>
</element>
</optional>
<element name="item">
<data type="byte"/>
</element>
</oneOrMore>
</element>
"""
# Memory debug specific
libxml2.debugMemory(1)
#
# Parse the Relax NG Schemas
#
rngp = libxml2.relaxNGNewMemParserCtxt(schema, len(schema))
rngs = rngp.relaxNGParse()
del rngp
#
# Parse and validate the correct document
#
docstr="""<foo>
<label>some text</label>
<item>100</item>
</foo>"""
f = str_io(docstr)
input = libxml2.inputBuffer(f)
reader = input.newTextReader("correct")
reader.RelaxNGSetSchema(rngs)
ret = reader.Read()
while ret == 1:
ret = reader.Read()
if ret != 0:
print("Error parsing the document")
sys.exit(1)
if reader.IsValid() != 1:
print("Document failed to validate")
sys.exit(1)
#
# Parse and validate the incorrect document
#
docstr="""<foo>
<label>some text</label>
<item>1000</item>
</foo>"""
err=""
# RNG errors are not as good as before , TODO
#expect="""RNG validity error: file error line 3 element text
#Type byte doesn't allow value '1000'
#RNG validity error: file error line 3 element text
#Error validating datatype byte
#RNG validity error: file error line 3 element text
#Element item failed to validate content
#"""
expect="""Type byte doesn't allow value '1000'
Error validating datatype byte
Element item failed to validate content
"""
def callback(ctx, str):
global err
err = err + "%s" % (str)
libxml2.registerErrorHandler(callback, "")
f = str_io(docstr)
input = libxml2.inputBuffer(f)
reader = input.newTextReader("error")
reader.RelaxNGSetSchema(rngs)
ret = reader.Read()
while ret == 1:
ret = reader.Read()
if ret != 0:
print("Error parsing the document")
sys.exit(1)
if reader.IsValid() != 0:
print("Document failed to detect the validation error")
sys.exit(1)
if err != expect:
print("Did not get the expected error message:")
print(err)
sys.exit(1)
#
# cleanup
#
del f
del input
del reader
del rngs
libxml2.relaxNGCleanupTypes()
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+101
View File
@@ -0,0 +1,101 @@
#!/usr/bin/env python3
#
# this tests the entities substitutions with the XmlTextReader interface
#
import sys
import setup_test
import libxml2
# Memory debug specific
libxml2.debugMemory(1)
result = ""
def processNode(reader):
global result
result = result + "%d %d %s %d\n" % (reader.Depth(), reader.NodeType(),
reader.Name(), reader.IsEmptyElement())
#
# Parse a document testing the readerForxxx API
#
docstr="""<foo>
<label>some text</label>
<item>100</item>
</foo>"""
expect="""0 1 foo 0
1 14 #text 0
1 1 label 0
2 3 #text 0
1 15 label 0
1 14 #text 0
1 1 item 0
2 3 #text 0
1 15 item 0
1 14 #text 0
0 15 foo 0
"""
result = ""
reader = libxml2.readerForDoc(docstr, "test1", None, 0)
ret = reader.Read()
while ret == 1:
processNode(reader)
ret = reader.Read()
if ret != 0:
print("Error parsing the document test1")
sys.exit(1)
if result != expect:
print("Unexpected result for test1")
print(result)
sys.exit(1)
#
# Reuse the reader for another document testing the ReaderNewxxx API
#
docstr="""<foo>
<label>some text</label>
<item>1000</item>
</foo>"""
expect="""0 1 foo 0
1 14 #text 0
1 1 label 0
2 3 #text 0
1 15 label 0
1 14 #text 0
1 1 item 0
2 3 #text 0
1 15 item 0
1 14 #text 0
0 15 foo 0
"""
result = ""
reader.NewDoc(docstr, "test2", None, 0)
ret = reader.Read()
while ret == 1:
processNode(reader)
ret = reader.Read()
if ret != 0:
print("Error parsing the document test2")
sys.exit(1)
if result != expect:
print("Unexpected result for test2")
print(result)
sys.exit(1)
#
# cleanup
#
del reader
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+36
View File
@@ -0,0 +1,36 @@
#!/usr/bin/env python3
#
# this tests the entities substitutions with the XmlTextReader interface
#
import sys
import setup_test
import libxml2
# Memory debug specific
libxml2.debugMemory(1)
#
# Parse a document testing the Close() API
#
docstr="""<foo>
<label>some text</label>
<item>100</item>
</foo>"""
reader = libxml2.readerForDoc(docstr, "test1", None, 0)
ret = reader.Read()
ret = reader.Read()
ret = reader.Close()
if ret != 0:
print("Error closing the document test1")
sys.exit(1)
del reader
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+56
View File
@@ -0,0 +1,56 @@
#!/usr/bin/env python3
#
# this tests the basic APIs of the XmlTextReader interface
#
import setup_test
import libxml2
import sys
try:
import StringIO
str_io = StringIO.StringIO
except:
import io
str_io = io.StringIO
# Memory debug specific
libxml2.debugMemory(1)
expect="""--> (3) test1:1:xmlns: URI foo is not absolute
--> (4) test1:1:Opening and ending tag mismatch: c line 1 and a
"""
err=""
def myErrorHandler(arg,msg,severity,locator):
global err
err = err + "%s (%d) %s:%d:%s" % (arg,severity,locator.BaseURI(),locator.LineNumber(),msg)
f = str_io("""<a xmlns="foo"><b b1="b1"/><c>content of c</a>""")
input = libxml2.inputBuffer(f)
reader = input.newTextReader("test1")
reader.SetErrorHandler(myErrorHandler,"-->")
while reader.Read() == 1:
pass
if err != expect:
print("error")
print("received %s" %(err))
print("expected %s" %(expect))
sys.exit(1)
reader.SetErrorHandler(None,None)
if reader.GetErrorHandler() != (None,None):
print("GetErrorHandler failed")
sys.exit(1)
#
# cleanup for memory allocation counting
#
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)))
+86
View File
@@ -0,0 +1,86 @@
#!/usr/bin/env python3
# -*- coding: ISO-8859-1 -*-
#
# this tests the next API of the XmlTextReader interface
#
import setup_test
import libxml2
import sys
try:
import StringIO
str_io = StringIO.StringIO
except:
import io
str_io = io.StringIO
# Memory debug specific
libxml2.debugMemory(1)
f = str_io("""<a><b><c /></b><d>content of d</d></a>""")
input = libxml2.inputBuffer(f)
reader = input.newTextReader("test_next")
ret = reader.Read()
if ret != 1:
print("test_next: 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("test_next: Error reading the first element")
sys.exit(1)
ret = reader.Read()
if ret != 1:
print("test_next: Error reading to second element")
sys.exit(1)
if reader.Name() != "b" or reader.IsEmptyElement() != 0 or \
reader.NodeType() != 1 or reader.HasAttributes() != 0:
print("test_next: Error reading the second element")
sys.exit(1)
ret = reader.Read()
if ret != 1:
print("test_next: Error reading to third element")
sys.exit(1)
if reader.Name() != "c" or reader.NodeType() != 1 or \
reader.HasAttributes() != 0:
print("test_next: Error reading the third element")
sys.exit(1)
ret = reader.Read()
if ret != 1:
print("test_next: Error reading to end of third element")
sys.exit(1)
if reader.Name() != "b" or reader.NodeType() != 15:
print("test_next: Error reading to end of second element")
sys.exit(1)
ret = reader.Next()
if ret != 1:
print("test_next: Error moving to third element")
sys.exit(1)
if reader.Name() != "d" or reader.IsEmptyElement() != 0 or \
reader.NodeType() != 1 or reader.HasAttributes() != 0:
print("test_next: Error reading third element")
sys.exit(1)
ret = reader.Next()
if ret != 1:
print("test_next: 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("test_next: Error reading the end of first element")
sys.exit(1)
ret = reader.Read()
if ret != 0:
print("test_next: Error reading to end of document")
sys.exit(1)
#
# cleanup for memory allocation counting
#
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)))
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/env python3
import sys
import setup_test
import libxml2
# Memory debug specific
libxml2.debugMemory(1)
def check_regex(regex, inside, outside):
re = libxml2.regexpCompile(regex)
for c in inside:
if re.regexpExec(c) != 1:
print("error checking inside", repr(regex), repr(c))
sys.exit(1)
for c in outside:
if re.regexpExec(c) != 0:
print("error checking outside", repr(regex), repr(c))
sys.exit(1)
if re.regexpIsDeterminist() != 1:
print("error checking determinism")
sys.exit(1)
del re
check_regex("a|b", "ab", ["ab", ""])
# https://gitlab.gnome.org/GNOME/libxml2/-/issues/1086
check_regex(r"[\t-\r]", "\t\n\r", ["a", "(", ""])
check_regex("[\\t-\\r]", "\t\n\r", ["a", "(", ""])
check_regex(r"[\[-\]]", "[]\\", "Z^")
check_regex(r"[\*-/]", "*+,-./", "()0")
# Non-standard escape sequences
check_regex(r"[\u0041-\u005A]", "ABCMYZ", ["a", "0", "[", ""])
check_regex(r"[\u0009\u0061-\u007A]", "\tabcmyz", ["A", "0", "{", "", "\n"])
check_regex(r"[\!-\%]", '!"#$%', ["&", " ", "a", ""])
check_regex(r"[\:-\>]", ':;<=>', ["?", "9", "@", ""])
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+48
View File
@@ -0,0 +1,48 @@
#!/usr/bin/env python3
import setup_test
import libxml2
import sys
# Memory debug specific
libxml2.debugMemory(1)
schema="""<?xml version="1.0"?>
<element name="foo"
xmlns="http://relaxng.org/ns/structure/1.0"
xmlns:a="http://relaxng.org/ns/annotation/1.0"
xmlns:ex1="http://www.example.com/n1"
xmlns:ex2="http://www.example.com/n2">
<a:documentation>A foo element.</a:documentation>
<element name="ex1:bar1">
<empty/>
</element>
<element name="ex2:bar2">
<empty/>
</element>
</element>
"""
instance="""<?xml version="1.0"?>
<foo><pre1:bar1 xmlns:pre1="http://www.example.com/n1"/><pre2:bar2 xmlns:pre2="http://www.example.com/n2"/></foo>"""
rngp = libxml2.relaxNGNewMemParserCtxt(schema, len(schema))
rngs = rngp.relaxNGParse()
ctxt = rngs.relaxNGNewValidCtxt()
doc = libxml2.parseDoc(instance)
ret = doc.relaxNGValidateDoc(ctxt)
if ret != 0:
print("error doing RelaxNG validation")
sys.exit(1)
doc.freeDoc()
del rngp
del rngs
del ctxt
libxml2.relaxNGCleanupTypes()
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+44
View File
@@ -0,0 +1,44 @@
#!/usr/bin/env python3
import sys
import setup_test
import libxml2
try:
import StringIO
str_io = StringIO.StringIO
except:
import io
str_io = io.StringIO
# Memory debug specific
libxml2.debugMemory(1)
def myResolver(URL, ID, ctxt):
return(str_io("<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)))
+52
View File
@@ -0,0 +1,52 @@
#!/usr/bin/env python3
import setup_test
import libxml2
import sys
# Memory debug specific
libxml2.debugMemory(1)
schema="""<?xml version="1.0" encoding="iso-8859-1"?>
<schema xmlns = "http://www.w3.org/2001/XMLSchema">
<element name = "Customer">
<complexType>
<sequence>
<element name = "FirstName" type = "string" />
<element name = "MiddleInitial" type = "string" />
<element name = "LastName" type = "string" />
</sequence>
<attribute name = "customerID" type = "integer" />
</complexType>
</element>
</schema>"""
instance="""<?xml version="1.0" encoding="iso-8859-1"?>
<Customer customerID = "24332">
<FirstName>Raymond</FirstName>
<MiddleInitial>G</MiddleInitial>
<LastName>Bayliss</LastName>
</Customer>
"""
ctxt_parser = libxml2.schemaNewMemParserCtxt(schema, len(schema))
ctxt_schema = ctxt_parser.schemaParse()
ctxt_valid = ctxt_schema.schemaNewValidCtxt()
doc = libxml2.parseDoc(instance)
ret = doc.schemaValidateDoc(ctxt_valid)
if ret != 0:
print("error doing schema validation")
sys.exit(1)
doc.freeDoc()
del ctxt_parser
del ctxt_schema
del ctxt_valid
libxml2.schemaCleanupTypes()
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+144
View File
@@ -0,0 +1,144 @@
#!/usr/bin/env python3
import sys
import setup_test
import libxml2
# Memory debug specific
libxml2.debugMemory(1)
#
# Testing XML document serialization
#
doc = libxml2.parseDoc("""<root><foo>hello</foo></root>""")
str = doc.serialize()
if str != """<?xml version="1.0"?>
<root><foo>hello</foo></root>
""":
print("error serializing XML document 1")
sys.exit(1)
str = doc.serialize("iso-8859-1")
if str != """<?xml version="1.0" encoding="iso-8859-1"?>
<root><foo>hello</foo></root>
""":
print("error serializing XML document 2")
sys.exit(1)
str = doc.serialize(format=1)
if str != """<?xml version="1.0"?>
<root>
<foo>hello</foo>
</root>
""":
print("error serializing XML document 3")
sys.exit(1)
str = doc.serialize("iso-8859-1", 1)
if str != """<?xml version="1.0" encoding="iso-8859-1"?>
<root>
<foo>hello</foo>
</root>
""":
print("error serializing XML document 4")
sys.exit(1)
#
# Test serializing a subnode
#
root = doc.getRootElement()
str = root.serialize()
if str != """<root><foo>hello</foo></root>""":
print("error serializing XML root 1")
sys.exit(1)
str = root.serialize("iso-8859-1")
if str != """<root><foo>hello</foo></root>""":
print("error serializing XML root 2")
sys.exit(1)
str = root.serialize(format=1)
if str != """<root>
<foo>hello</foo>
</root>""":
print("error serializing XML root 3")
sys.exit(1)
str = root.serialize("iso-8859-1", 1)
if str != """<root>
<foo>hello</foo>
</root>""":
print("error serializing XML root 4")
sys.exit(1)
doc.freeDoc()
#
# Testing HTML document serialization
#
doc = libxml2.htmlParseDoc("""<html><head><title>Hello</title><body><p>hello</body></html>""", None)
str = doc.serialize()
if str != """<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><head><title>Hello</title></head><body><p>hello</p></body></html>
""":
print("error serializing HTML document 1")
sys.exit(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">
<html><head><meta charset="ISO-8859-1"><title>Hello</title></head><body><p>hello</p></body></html>
""":
print("error serializing HTML document 2")
sys.exit(1)
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">
<html>
<head><title>Hello</title></head>
<body><p>hello</p></body>
</html>
""":
print("error serializing HTML document 3")
sys.exit(1)
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">
<html>
<head>
<meta charset="iso-8859-1">
<title>Hello</title>
</head>
<body><p>hello</p></body>
</html>
""":
print("error serializing HTML document 4", str)
sys.exit(1)
#
# Test serializing a subnode
#
doc.htmlSetMetaEncoding(None)
root = doc.getRootElement()
str = root.serialize()
if str != """<html><head><title>Hello</title></head><body><p>hello</p></body></html>""":
print("error serializing HTML root 1")
sys.exit(1)
str = root.serialize("ISO-8859-1")
if str != """<html><head><meta charset="ISO-8859-1"><title>Hello</title></head><body><p>hello</p></body></html>""":
print("error serializing HTML root 2")
sys.exit(1)
str = root.serialize(format=1)
if str != """<html>
<head><title>Hello</title></head>
<body><p>hello</p></body>
</html>""":
print("error serializing HTML root 3")
sys.exit(1)
str = root.serialize("iso-8859-1", 1)
if str != """<html>
<head>
<meta charset="iso-8859-1">
<title>Hello</title>
</head>
<body><p>hello</p></body>
</html>""":
print("error serializing HTML root 4")
sys.exit(1)
doc.freeDoc()
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+5
View File
@@ -0,0 +1,5 @@
import os
import sys
if hasattr(os, 'add_dll_directory'):
os.add_dll_directory(os.path.join(os.getcwd(), '..', '..', '.libs'))
+138
View File
@@ -0,0 +1,138 @@
#!/usr/bin/env python3
import sys
import setup_test
import libxml2
# Memory debug specific
libxml2.debugMemory(1)
log = ""
class callback:
def startDocument(self):
global log
log = log + "startDocument:"
def endDocument(self):
global log
log = log + "endDocument:"
def startElement(self, tag, attrs):
global log
log = log + "startElement %s %s:" % (tag, attrs)
def endElement(self, tag):
global log
log = log + "endElement %s:" % (tag)
def characters(self, data):
global log
log = log + "characters: %s:" % (data)
def warning(self, msg):
global log
log = log + "warning: %s:" % (msg)
def error(self, msg):
global log
log = log + "error: %s:" % (msg)
def fatalError(self, msg):
global log
log = log + "fatalError: %s:" % (msg)
handler = callback()
log=""
chunk="""<foo><bar2/>"""
ctxt = libxml2.createPushParser(handler, None, 0, "test.xml")
ctxt.parseChunk(chunk, len(chunk), 0)
ctxt=None
reference = "startDocument:startElement foo None:startElement bar2 None:endElement bar2:"
if log != reference:
print("Error got: %s" % log)
print("Expected: %s" % reference)
sys.exit(1)
log=""
chunk="""<foo><bar2></bar2>"""
ctxt = libxml2.createPushParser(handler, None, 0, "test.xml")
ctxt.parseChunk(chunk, len(chunk), 0)
ctxt=None
reference = "startDocument:startElement foo None:startElement bar2 None:endElement bar2:"
if log != reference:
print("Error got: %s" % log)
print("Expected: %s" % reference)
sys.exit(1)
log=""
chunk="""<foo><bar2>"""
ctxt = libxml2.createPushParser(handler, None, 0, "test.xml")
ctxt.parseChunk(chunk, len(chunk), 0)
ctxt=None
reference = "startDocument:startElement foo None:startElement bar2 None:"
if log != reference:
print("Error got: %s" % log)
print("Expected: %s" % reference)
sys.exit(1)
log=""
chunk="""<foo><bar2 a="1" b='2' />"""
ctxt = libxml2.createPushParser(handler, None, 0, "test.xml")
ctxt.parseChunk(chunk, len(chunk), 0)
ctxt=None
reference1 = "startDocument:startElement foo None:startElement bar2 {'a': '1', 'b': '2'}:endElement bar2:"
reference2 = "startDocument:startElement foo None:startElement bar2 {'b': '2', 'a': '1'}:endElement bar2:"
if log not in (reference1, reference2):
print("Error got: %s" % log)
print("Expected: %s" % reference)
sys.exit(1)
log=""
chunk="""<foo><bar2 a="1" b='2' >"""
ctxt = libxml2.createPushParser(handler, None, 0, "test.xml")
ctxt.parseChunk(chunk, len(chunk), 0)
ctxt=None
reference1 = "startDocument:startElement foo None:startElement bar2 {'a': '1', 'b': '2'}:"
reference2 = "startDocument:startElement foo None:startElement bar2 {'b': '2', 'a': '1'}:"
if log not in (reference1, reference2):
print("Error got: %s" % log)
print("Expected: %s" % reference)
sys.exit(1)
log=""
chunk="""<foo><bar2 a="1" b='2' ></bar2>"""
ctxt = libxml2.createPushParser(handler, None, 0, "test.xml")
ctxt.parseChunk(chunk, len(chunk), 0)
ctxt=None
reference1 = "startDocument:startElement foo None:startElement bar2 {'a': '1', 'b': '2'}:endElement bar2:"
reference2 = "startDocument:startElement foo None:startElement bar2 {'b': '2', 'a': '1'}:endElement bar2:"
if log not in (reference1, reference2):
print("Error got: %s" % log)
print("Expected: %s" % reference)
sys.exit(1)
log=""
chunk="""<foo><bar2 a="b='1' />"""
ctxt = libxml2.createPushParser(handler, None, 0, "test.xml")
ctxt.parseChunk(chunk, len(chunk), 0)
ctxt=None
reference = "startDocument:startElement foo None:"
if log != reference:
print("Error got: %s" % log)
print("Expected: %s" % reference)
sys.exit(1)
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+1
View File
@@ -0,0 +1 @@
<!ELEMENT foo EMPTY>
+105
View File
@@ -0,0 +1,105 @@
#!/usr/bin/env python3
import string, sys, time
try:
from _thread import get_ident
except:
from thread import get_ident
from threading import Thread, Lock
import setup_test
import libxml2
# Memory debug specific
libxml2.debugMemory(1)
THREADS_COUNT = 15
failed = 0
class ErrorHandler:
def __init__(self):
self.errors = []
self.lock = Lock()
def handler(self,ctx,str):
self.lock.acquire()
self.errors.append(str)
self.lock.release()
def getPedanticParserDefault():
old = libxml2.pedanticParserDefault(0)
libxml2.pedanticParserDefault(old)
return old
def test(expectedPedanticParserDefault):
time.sleep(1)
global failed
# check a per thread-global
if expectedPedanticParserDefault != getPedanticParserDefault():
failed = 1
print("FAILED to obtain correct value for " \
"pedanticParserDefault in thread %d" % get_ident())
# check the global error handler
# (which is NOT per-thread in the python bindings)
try:
doc = libxml2.parseFile("bad.xml")
except:
pass
else:
assert "failed"
# global error handler
eh = ErrorHandler()
libxml2.registerErrorHandler(eh.handler,"")
# set on the main thread only
libxml2.pedanticParserDefault(1)
test(1)
ec = len(eh.errors)
if ec == 0:
print("FAILED: should have obtained errors")
sys.exit(1)
ts = []
for i in range(THREADS_COUNT):
# expect 0 for pedanticParserDefault because
# the new value has been set on the main thread only
ts.append(Thread(target=test,args=(0,)))
for t in ts:
t.start()
for t in ts:
t.join()
if len(eh.errors) != ec+THREADS_COUNT*ec:
print("FAILED: did not obtain the correct number of errors")
sys.exit(1)
# set pedanticParserDefault for future new threads
libxml2.thrDefPedanticParserDefaultValue(1)
ts = []
for i in range(THREADS_COUNT):
# expect 1 for pedanticParserDefault
ts.append(Thread(target=test,args=(1,)))
for t in ts:
t.start()
for t in ts:
t.join()
if len(eh.errors) != ec+THREADS_COUNT*ec*2:
print("FAILED: did not obtain the correct number of errors")
sys.exit(1)
if failed:
print("FAILED")
sys.exit(1)
# Memory debug specific
libxml2.cleanupParser()
# Note that this can leak memory on Windows if the global state
# destructors weren't run yet. They should be called eventually,
# so this leak should be harmless.
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env python3
import sys
import setup_test
import libxml2
# Memory debug specific
libxml2.debugMemory(1)
doc = libxml2.parseFile("tst.xml")
if doc.name != "tst.xml":
print("doc.name failed")
sys.exit(1)
root = doc.children
if root.name != "doc":
print("root.name failed")
sys.exit(1)
child = root.children
if child.name != "foo":
print("child.name failed")
sys.exit(1)
doc.freeDoc()
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+1
View File
@@ -0,0 +1 @@
<doc><foo>bar</foo></doc>
+85
View File
@@ -0,0 +1,85 @@
#!/usr/bin/env python3
import sys, unittest
import setup_test
import libxml2
class TestCase(unittest.TestCase):
def runTest(self):
self.test1()
self.test2()
def setUp(self):
libxml2.debugMemory(1)
def tearDown(self):
libxml2.cleanupParser()
if libxml2.debugMemory(1) != 0:
self.fail("Memory leak %d bytes" % (libxml2.debugMemory(1),))
else:
print("OK")
def failUnlessXmlError(self,f,args,exc,domain,code,message,level,file,line):
"""Run function f, with arguments args and expect an exception exc;
when the exception is raised, check the libxml2.lastError for
expected values."""
# disable the default error handler
def noerr(ctx, str):
pass
# None is not acceptable as function.
libxml2.registerErrorHandler(noerr,None)
try:
f(*args)
except exc:
e = libxml2.lastError()
if e is None:
self.fail("lastError not set")
if 0:
print("domain = ",e.domain())
print("code = ",e.code())
print("message =",repr(e.message()))
print("level =",e.level())
print("file =",e.file())
print("line =",e.line())
print()
self.assertEqual(domain,e.domain())
self.assertEqual(code,e.code())
self.assertEqual(message,e.message())
self.assertEqual(level,e.level())
self.assertEqual(file,e.file())
self.assertEqual(line,e.line())
else:
self.fail("exception %s should have been raised" % exc)
def test1(self):
"""Test readFile with a file that does not exist"""
self.failUnlessXmlError(libxml2.readFile,
("dummy.xml",None,0),
libxml2.treeError,
domain=libxml2.XML_FROM_IO,
code=libxml2.XML_IO_ENOENT,
message='failed to load "dummy.xml": No such file or directory\n',
level=libxml2.XML_ERR_WARNING,
file=None,
line=0)
def test2(self):
"""Test a well-formedness error: we get the last error only"""
s = "<x>\n<a>\n</x>"
self.failUnlessXmlError(libxml2.readMemory,
(s,len(s),"dummy.xml",None,0),
libxml2.treeError,
domain=libxml2.XML_FROM_PARSER,
code=libxml2.XML_ERR_TAG_NAME_MISMATCH,
message='Opening and ending tag mismatch: a line 2 and x\n',
level=libxml2.XML_ERR_FATAL,
file='dummy.xml',
line=3)
if __name__ == "__main__":
test = TestCase()
test.setUp()
test.test1()
test.test2()
test.tearDown()
+41
View File
@@ -0,0 +1,41 @@
#!/usr/bin/env python3
import sys
import setup_test
import libxml2
# Memory debug specific
libxml2.debugMemory(1)
uri = libxml2.parseURI("http://example.org:8088/foo/bar?query=simple#fragid")
if uri.scheme() != 'http':
print("Error parsing URI: wrong scheme")
sys.exit(1)
if uri.server() != 'example.org':
print("Error parsing URI: wrong server")
sys.exit(1)
if uri.port() != 8088:
print("Error parsing URI: wrong port")
sys.exit(1)
if uri.path() != '/foo/bar':
print("Error parsing URI: wrong path")
sys.exit(1)
if uri.query() != 'query=simple':
print("Error parsing URI: wrong query")
sys.exit(1)
if uri.fragment() != 'fragid':
print("Error parsing URI: wrong query")
sys.exit(1)
uri.setScheme("https")
uri.setPort(223)
uri.setFragment(None)
result=uri.saveUri()
if result != "https://example.org:223/foo/bar?query=simple":
print("Error modifying or saving the URI")
uri = None
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+41
View File
@@ -0,0 +1,41 @@
#!/usr/bin/env python3
import setup_test
import libxml2
try:
import libxml2mod
except ModuleNotFoundError:
from libxmlmods import libxml2mod
import sys
def error(msg, data):
pass
# Memory debug specific
libxml2.debugMemory(1)
dtd="""<!ELEMENT foo EMPTY>"""
instance="""<?xml version="1.0"?>
<foo></foo>"""
dtd = libxml2.parseDTD(None, 'test.dtd')
ctxt = libxml2.newValidCtxt()
libxml2mod.xmlSetValidErrors(ctxt._o, error, error)
doc = libxml2.parseDoc(instance)
ret = doc.validateDtd(ctxt, dtd)
if ret != 1:
print("error doing DTD validation")
sys.exit(1)
doc.freeDoc()
dtd.freeDtd()
del dtd
del ctxt
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+63
View File
@@ -0,0 +1,63 @@
#!/usr/bin/env python3
import sys
import setup_test
import libxml2
#memory debug specific
libxml2.debugMemory(1)
called = ""
def foo(ctx, x):
global called
#
# test that access to the XPath evaluation contexts
#
pctxt = libxml2.xpathParserContext(_obj=ctx)
ctxt = pctxt.context()
called = ctxt.function()
return x + 1
def bar(ctxt, x):
return "%d" % (x + 2)
doc = libxml2.parseFile("tst.xml")
ctxt = doc.xpathNewContext()
res = ctxt.xpathEval("//*")
if len(res) != 2:
print("xpath query: wrong node set size")
sys.exit(1)
if res[0].name != "doc" or res[1].name != "foo":
print("xpath query: wrong node set value")
sys.exit(1)
libxml2.registerXPathFunction(ctxt._o, "foo", None, foo)
libxml2.registerXPathFunction(ctxt._o, "bar", None, bar)
i = 10000
while i > 0:
res = ctxt.xpathEval("foo(1)")
if res != 2:
print("xpath extension failure")
sys.exit(1)
i = i - 1
i = 10000
while i > 0:
res = ctxt.xpathEval("bar(1)")
if res != "3":
print("xpath extension failure got %s expecting '3'")
sys.exit(1)
i = i - 1
doc.freeDoc()
ctxt.xpathFreeContext()
if called != "foo":
print("xpath function: failed to access the context")
print("xpath function: %s" % (called))
sys.exit(1)
#memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+61
View File
@@ -0,0 +1,61 @@
from io import BytesIO, StringIO
import libxml2
import sys
from xml.sax.handler import ContentHandler
from xml.sax.xmlreader import InputSource
import xml.sax
# Test data: an XML file with a 100,000 Unicode smileys, which expand
# into 400,000 bytes after UTF-8 encoding.
SMILEY = '\U0001f600'
TEXT = 100_000 * SMILEY
XML_STRING = '<?xml version="1.0" encoding="UTF-8" ?>\n<root>' + TEXT + '</root>'
XML_BYTES = XML_STRING.encode('utf-8')
def RunTest(test_name, source):
expected = TEXT
received = ''
class TestHandler(ContentHandler):
def characters(self, content):
nonlocal received
received += content
reader = xml.sax.make_parser(['drv_libxml2'])
reader.setContentHandler(TestHandler())
reader.parse(source)
if expected != received:
print(test_name, 'failed!')
print('Expected length:', len(expected))
print('Received length:', len(received))
print('Expected text: (prefix only)', expected[:100])
print('Received text: (prefix only)', received[:100])
sys.exit(1)
def TestBytesInput():
source = InputSource()
source.setByteStream(BytesIO(XML_BYTES))
RunTest('TestBytesInput', source)
def TestStringInput():
source = InputSource()
source.setCharacterStream(StringIO(XML_STRING))
RunTest('TestStringInput', source)
# Memory debug specific
libxml2.debugMemory(1)
TestBytesInput()
TestStringInput()
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+4
View File
@@ -0,0 +1,4 @@
<!DOCTYPE doc [
<!ELEMENT doc EMPTY>
]>
<doc/>
+59
View File
@@ -0,0 +1,59 @@
#!/usr/bin/env python3
import setup_test
import libxml2
import sys
ARG = 'test string'
class ErrorHandler:
def __init__(self):
self.errors = []
def handler(self, msg, data):
if data != ARG:
raise Exception("Error handler did not receive correct argument")
self.errors.append(msg)
# Memory debug specific
libxml2.debugMemory(1)
dtd="""<!ELEMENT foo EMPTY>"""
valid="""<?xml version="1.0"?>
<foo></foo>"""
invalid="""<?xml version="1.0"?>
<foo><bar/></foo>"""
dtd = libxml2.parseDTD(None, 'test.dtd')
ctxt = libxml2.newValidCtxt()
e = ErrorHandler()
ctxt.setValidityErrorHandler(e.handler, e.handler, ARG)
# Test valid document
doc = libxml2.parseDoc(valid)
ret = doc.validateDtd(ctxt, dtd)
if ret != 1 or e.errors:
print("error doing DTD validation")
sys.exit(1)
doc.freeDoc()
# Test invalid document
doc = libxml2.parseDoc(invalid)
ret = doc.validateDtd(ctxt, dtd)
if ret != 0 or not e.errors:
print("Error: document supposed to be invalid")
doc.freeDoc()
dtd.freeDtd()
del dtd
del ctxt
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+76
View File
@@ -0,0 +1,76 @@
#!/usr/bin/env python3
import setup_test
import libxml2
import sys
ARG = 'test string'
class ErrorHandler:
def __init__(self):
self.errors = []
def handler(self, msg, data):
if data != ARG:
raise Exception("Error handler did not receive correct argument")
self.errors.append(msg)
# Memory debug specific
libxml2.debugMemory(1)
schema="""<?xml version="1.0"?>
<element name="foo"
xmlns="http://relaxng.org/ns/structure/1.0"
xmlns:a="http://relaxng.org/ns/annotation/1.0"
xmlns:ex1="http://www.example.com/n1"
xmlns:ex2="http://www.example.com/n2">
<a:documentation>A foo element.</a:documentation>
<element name="ex1:bar1">
<empty/>
</element>
<element name="ex2:bar2">
<empty/>
</element>
</element>
"""
valid="""<?xml version="1.0"?>
<foo><pre1:bar1 xmlns:pre1="http://www.example.com/n1"/><pre2:bar2 xmlns:pre2="http://www.example.com/n2"/></foo>"""
invalid="""<?xml version="1.0"?>
<foo><pre1:bar1 xmlns:pre1="http://www.example.com/n1">bad</pre1:bar1><pre2:bar2 xmlns:pre2="http://www.example.com/n2"/></foo>"""
rngp = libxml2.relaxNGNewMemParserCtxt(schema, len(schema))
rngs = rngp.relaxNGParse()
ctxt = rngs.relaxNGNewValidCtxt()
e = ErrorHandler()
ctxt.setValidityErrorHandler(e.handler, e.handler, ARG)
# Test valid document
doc = libxml2.parseDoc(valid)
ret = doc.relaxNGValidateDoc(ctxt)
if ret != 0 or e.errors:
print("error doing RelaxNG validation")
sys.exit(1)
doc.freeDoc()
# Test invalid document
doc = libxml2.parseDoc(invalid)
ret = doc.relaxNGValidateDoc(ctxt)
if ret == 0 or not e.errors:
print("Error: document supposed to be RelaxNG invalid")
sys.exit(1)
doc.freeDoc()
del rngp
del rngs
del ctxt
libxml2.relaxNGCleanupTypes()
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+83
View File
@@ -0,0 +1,83 @@
#!/usr/bin/env python3
import setup_test
import libxml2
import sys
ARG = 'test string'
class ErrorHandler:
def __init__(self):
self.errors = []
def handler(self, msg, data):
if data != ARG:
raise Exception("Error handler did not receive correct argument")
self.errors.append(msg)
# Memory debug specific
libxml2.debugMemory(1)
schema="""<?xml version="1.0" encoding="iso-8859-1"?>
<schema xmlns = "http://www.w3.org/2001/XMLSchema">
<element name = "Customer">
<complexType>
<sequence>
<element name = "FirstName" type = "string" />
<element name = "MiddleInitial" type = "string" />
<element name = "LastName" type = "string" />
</sequence>
<attribute name = "customerID" type = "integer" />
</complexType>
</element>
</schema>"""
valid="""<?xml version="1.0" encoding="iso-8859-1"?>
<Customer customerID = "24332">
<FirstName>Raymond</FirstName>
<MiddleInitial>G</MiddleInitial>
<LastName>Bayliss</LastName>
</Customer>
"""
invalid="""<?xml version="1.0" encoding="iso-8859-1"?>
<Customer customerID = "24332">
<MiddleInitial>G</MiddleInitial>
<LastName>Bayliss</LastName>
</Customer>
"""
e = ErrorHandler()
ctxt_parser = libxml2.schemaNewMemParserCtxt(schema, len(schema))
ctxt_schema = ctxt_parser.schemaParse()
ctxt_valid = ctxt_schema.schemaNewValidCtxt()
ctxt_valid.setValidityErrorHandler(e.handler, e.handler, ARG)
# Test valid document
doc = libxml2.parseDoc(valid)
ret = doc.schemaValidateDoc(ctxt_valid)
if ret != 0 or e.errors:
print("error doing schema validation")
sys.exit(1)
doc.freeDoc()
# Test invalid document
doc = libxml2.parseDoc(invalid)
ret = doc.schemaValidateDoc(ctxt_valid)
if ret == 0 or not e.errors:
print("Error: document supposer to be schema invalid")
sys.exit(1)
doc.freeDoc()
del ctxt_parser
del ctxt_schema
del ctxt_valid
libxml2.schemaCleanupTypes()
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+82
View File
@@ -0,0 +1,82 @@
#!/usr/bin/env python3
import sys
import setup_test
import libxml2
# Memory debug specific
libxml2.debugMemory(1)
ctxt = libxml2.createFileParserCtxt("valid.xml")
ctxt.validate(1)
ctxt.parseDocument()
doc = ctxt.doc()
valid = ctxt.isValid()
if doc.name != "valid.xml":
print("doc.name failed")
sys.exit(1)
root = doc.children
if root.name != "doc":
print("root.name failed")
sys.exit(1)
if valid != 1:
print("validity check failed")
sys.exit(1)
doc.freeDoc()
i = 1000
while i > 0:
ctxt = libxml2.createFileParserCtxt("valid.xml")
ctxt.validate(1)
ctxt.parseDocument()
doc = ctxt.doc()
valid = ctxt.isValid()
doc.freeDoc()
if valid != 1:
print("validity check failed")
sys.exit(1)
i = i - 1
#deactivate error messages from the validation
def noerr(ctx, str):
pass
libxml2.registerErrorHandler(noerr, None)
ctxt = libxml2.createFileParserCtxt("invalid.xml")
ctxt.validate(1)
ctxt.parseDocument()
doc = ctxt.doc()
valid = ctxt.isValid()
if doc.name != "invalid.xml":
print("doc.name failed")
sys.exit(1)
root = doc.children
if root.name != "doc":
print("root.name failed")
sys.exit(1)
if valid != 0:
print("validity check failed")
sys.exit(1)
doc.freeDoc()
i = 1000
while i > 0:
ctxt = libxml2.createFileParserCtxt("invalid.xml")
ctxt.validate(1)
ctxt.parseDocument()
doc = ctxt.doc()
valid = ctxt.isValid()
doc.freeDoc()
if valid != 0:
print("validity check failed")
sys.exit(1)
i = i - 1
del ctxt
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+144
View File
@@ -0,0 +1,144 @@
#!/usr/bin/env python3
#
# this tests the entities substitutions with the XmlTextReader interface
#
import sys
import setup_test
import libxml2
# Memory debug specific
libxml2.debugMemory(1)
result = ""
def processNode(reader):
global result
result = result + "%d %d %s %d\n" % (reader.Depth(), reader.NodeType(),
reader.Name(), reader.IsEmptyElement())
#
# Parse a document testing the readerForxxx API
#
docstr="""<foo>
<label>some text</label>
<item>100</item>
</foo>"""
expect="""0 1 foo 0
1 14 #text 0
1 1 label 0
2 3 #text 0
1 15 label 0
1 14 #text 0
1 1 item 0
2 3 #text 0
1 15 item 0
1 14 #text 0
0 15 foo 0
"""
result = ""
doc = libxml2.parseDoc(docstr)
reader = doc.readerWalker();
ret = reader.Read()
while ret == 1:
processNode(reader)
ret = reader.Read()
if ret != 0:
print("Error parsing the document test1")
sys.exit(1)
if result != expect:
print("Unexpected result for test1")
print(result)
sys.exit(1)
doc.freeDoc()
#
# Reuse the reader for another document testing the ReaderNewWalker API
#
docstr="""<foo>
<label>some text</label>
<item>1000</item>
</foo>"""
expect="""0 1 foo 0
1 14 #text 0
1 1 label 0
2 3 #text 0
1 15 label 0
1 14 #text 0
1 1 item 0
2 3 #text 0
1 15 item 0
1 14 #text 0
0 15 foo 0
"""
result = ""
doc = libxml2.parseDoc(docstr)
reader.NewWalker(doc)
ret = reader.Read()
while ret == 1:
processNode(reader)
ret = reader.Read()
if ret != 0:
print("Error parsing the document test2")
sys.exit(1)
if result != expect:
print("Unexpected result for test2")
print(result)
sys.exit(1)
doc.freeDoc()
#
# Reuse the reader for another document testing the ReaderNewxxx API
#
docstr="""<foo>
<label>some text</label>
<item>1000</item>
</foo>"""
expect="""0 1 foo 0
1 14 #text 0
1 1 label 0
2 3 #text 0
1 15 label 0
1 14 #text 0
1 1 item 0
2 3 #text 0
1 15 item 0
1 14 #text 0
0 15 foo 0
"""
result = ""
reader.NewDoc(docstr, "test3", None, 0)
ret = reader.Read()
while ret == 1:
processNode(reader)
ret = reader.Read()
if ret != 0:
print("Error parsing the document test3")
sys.exit(1)
if result != expect:
print("Unexpected result for test3")
print(result)
sys.exit(1)
#
# cleanup
#
del reader
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/env python3
#
# this test exercise the XPath basic engine, parser, etc, and
# allows to detect memory leaks
#
import sys
import setup_test
import libxml2
# Memory debug specific
libxml2.debugMemory(1)
doc = libxml2.parseFile("tst.xml")
if doc.name != "tst.xml":
print("doc.name error")
sys.exit(1);
ctxt = doc.xpathNewContext()
res = ctxt.xpathEval("//*")
if len(res) != 2:
print("xpath query: wrong node set size")
sys.exit(1)
if res[0].name != "doc" or res[1].name != "foo":
print("xpath query: wrong node set value")
sys.exit(1)
ctxt.setContextNode(res[0])
res = ctxt.xpathEval("foo")
if len(res) != 1:
print("xpath query: wrong node set size")
sys.exit(1)
if res[0].name != "foo":
print("xpath query: wrong node set value")
sys.exit(1)
doc.freeDoc()
ctxt.xpathFreeContext()
i = 1000
while i > 0:
doc = libxml2.parseFile("tst.xml")
ctxt = doc.xpathNewContext()
res = ctxt.xpathEval("//*")
doc.freeDoc()
ctxt.xpathFreeContext()
i = i -1
del ctxt
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+49
View File
@@ -0,0 +1,49 @@
#!/usr/bin/env python3
import sys
import setup_test
import libxml2
# Memory debug specific
libxml2.debugMemory(1)
def foo(ctx, x):
return x + 1
def bar(ctx, x):
return "%d" % (x + 2)
doc = libxml2.parseFile("tst.xml")
ctxt = doc.xpathNewContext()
res = ctxt.xpathEval("//*")
if len(res) != 2:
print("xpath query: wrong node set size")
sys.exit(1)
if res[0].name != "doc" or res[1].name != "foo":
print("xpath query: wrong node set value")
sys.exit(1)
libxml2.registerXPathFunction(ctxt._o, "foo", None, foo)
libxml2.registerXPathFunction(ctxt._o, "bar", None, bar)
i = 10000
while i > 0:
res = ctxt.xpathEval("foo(1)")
if res != 2:
print("xpath extension failure")
sys.exit(1)
i = i - 1
i = 10000
while i > 0:
res = ctxt.xpathEval("bar(1)")
if res != "3":
print("xpath extension failure got %s expecting '3'")
sys.exit(1)
i = i - 1
doc.freeDoc()
ctxt.xpathFreeContext()
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+55
View File
@@ -0,0 +1,55 @@
#!/usr/bin/env python3
import setup_test
import libxml2
import sys
libxml2.debugMemory(True)
expect="""--> Invalid expression
--> Invalid expression
--> Invalid expression
--> Invalid expression
--> Invalid expression
--> Invalid expression
--> Invalid expression
--> Invalid expression
--> Invalid expression
--> Invalid expression
"""
err=""
def callback(ctx, str):
global err
err = err + "%s %s" % (ctx, str)
libxml2.registerErrorHandler(callback, "-->")
doc = libxml2.parseDoc("<fish/>")
ctxt = doc.xpathNewContext()
ctxt.setContextNode(doc)
badexprs = (
":false()", "bad:()", "bad(:)", ":bad(:)", "bad:(:)", "bad:bad(:)",
"a:/b", "/c:/d", "//e:/f", "g://h"
)
for expr in badexprs:
try:
ctxt.xpathEval(expr)
except libxml2.xpathError:
pass
else:
print("Unexpectedly legal expression:", expr)
ctxt.xpathFreeContext()
doc.freeDoc()
if err != expect:
print("error")
print("received %s" %(err))
print("expected %s" %(expect))
sys.exit(1)
libxml2.cleanupParser()
leakedbytes = libxml2.debugMemory(True)
if leakedbytes == 0:
print("OK")
else:
print("Memory leak", leakedbytes, "bytes")
+29
View File
@@ -0,0 +1,29 @@
#!/usr/bin/env python3
#
import setup_test
import libxml2
expect=' xmlns:a="urn:whatevar"'
# Memory debug specific
libxml2.debugMemory(1)
d = libxml2.parseDoc("<a:a xmlns:a='urn:whatevar'/>")
res=""
for n in d.xpathEval("//namespace::*"):
res = res + n.serialize()
del n
d.freeDoc()
if res != expect:
print("test5 failed: unexpected output")
print(res)
del res
del d
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+57
View File
@@ -0,0 +1,57 @@
#!/usr/bin/env python3
import sys
import setup_test
import libxml2
#memory debug specific
libxml2.debugMemory(1)
#
# A document hosting the nodes returned from the extension function
#
mydoc = libxml2.newDoc("1.0")
def foo(ctx, str):
global mydoc
#
# test returning a node set works as expected
#
parent = mydoc.newDocNode(None, 'p', None)
mydoc.addChild(parent)
node = mydoc.newDocText(str)
parent.addChild(node)
return [parent]
doc = libxml2.parseFile("tst.xml")
ctxt = doc.xpathNewContext()
libxml2.registerXPathFunction(ctxt._o, "foo", None, foo)
res = ctxt.xpathEval("foo('hello')")
if type(res) != type([]):
print("Failed to return a nodeset")
sys.exit(1)
if len(res) != 1:
print("Unexpected nodeset size")
sys.exit(1)
node = res[0]
if node.name != 'p':
print("Unexpected nodeset element result")
sys.exit(1)
node = node.children
if node.type != 'text':
print("Unexpected nodeset element children type")
sys.exit(1)
if node.content != 'hello':
print("Unexpected nodeset element children content")
sys.exit(1)
doc.freeDoc()
mydoc.freeDoc()
ctxt.xpathFreeContext()
#memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print("OK")
else:
print("Memory leak %d bytes" % (libxml2.debugMemory(1)))