1#!/usr/bin/python -u
2# -*- coding: ISO-8859-1 -*-
3#
4# this tests the basic APIs of the XmlTextReader interface
5#
6import libxml2
7import StringIO
8import sys
9
10# Memory debug specific
11libxml2.debugMemory(1)
12
13f = StringIO.StringIO("""<a><b b1="b1"/><c>content of c</c></a>""")
14input = libxml2.inputBuffer(f)
15reader = input.newTextReader("test1")
16ret = reader.Read()
17if ret != 1:
18    print "test1: Error reading to first element"
19    sys.exit(1)
20if reader.Name() != "a" or reader.IsEmptyElement() != 0 or \
21   reader.NodeType() != 1 or reader.HasAttributes() != 0:
22    print "test1: Error reading the first element"
23    sys.exit(1)
24ret = reader.Read()
25if ret != 1:
26    print "test1: Error reading to second element"
27    sys.exit(1)
28if reader.Name() != "b" or reader.IsEmptyElement() != 1 or \
29   reader.NodeType() != 1 or reader.HasAttributes() != 1:
30    print "test1: Error reading the second element"
31    sys.exit(1)
32ret = reader.Read()
33if ret != 1:
34    print "test1: Error reading to third element"
35    sys.exit(1)
36if reader.Name() != "c" or reader.IsEmptyElement() != 0 or \
37   reader.NodeType() != 1 or reader.HasAttributes() != 0:
38    print "test1: Error reading the third element"
39    sys.exit(1)
40ret = reader.Read()
41if ret != 1:
42    print "test1: Error reading to text node"
43    sys.exit(1)
44if reader.Name() != "#text" or reader.IsEmptyElement() != 0 or \
45   reader.NodeType() != 3 or reader.HasAttributes() != 0 or \
46   reader.Value() != "content of c":
47    print "test1: Error reading the text node"
48    sys.exit(1)
49ret = reader.Read()
50if ret != 1:
51    print "test1: Error reading to end of third element"
52    sys.exit(1)
53if reader.Name() != "c" or reader.IsEmptyElement() != 0 or \
54   reader.NodeType() != 15 or reader.HasAttributes() != 0:
55    print "test1: Error reading the end of third element"
56    sys.exit(1)
57ret = reader.Read()
58if ret != 1:
59    print "test1: Error reading to end of first element"
60    sys.exit(1)
61if reader.Name() != "a" or reader.IsEmptyElement() != 0 or \
62   reader.NodeType() != 15 or reader.HasAttributes() != 0:
63    print "test1: Error reading the end of first element"
64    sys.exit(1)
65ret = reader.Read()
66if ret != 0:
67    print "test1: Error reading to end of document"
68    sys.exit(1)
69
70#
71# example from the XmlTextReader docs
72#
73f = StringIO.StringIO("""<test xmlns:dt="urn:datatypes" dt:type="int"/>""")
74input = libxml2.inputBuffer(f)
75reader = input.newTextReader("test2")
76
77ret = reader.Read()
78if ret != 1:
79    print "Error reading test element"
80    sys.exit(1)
81if reader.GetAttributeNo(0) != "urn:datatypes" or \
82   reader.GetAttributeNo(1) != "int" or \
83   reader.GetAttributeNs("type", "urn:datatypes") != "int" or \
84   reader.GetAttribute("dt:type") != "int":
85    print "error reading test attributes"
86    sys.exit(1)
87
88#
89# example from the XmlTextReader docs
90#
91f = StringIO.StringIO("""<root xmlns:a="urn:456">
92<item>
93<ref href="a:b"/>
94</item>
95</root>""")
96input = libxml2.inputBuffer(f)
97reader = input.newTextReader("test3")
98
99ret = reader.Read()
100while ret == 1:
101    if reader.Name() == "ref":
102        if reader.LookupNamespace("a") != "urn:456":
103            print "error resolving namespace prefix"
104            sys.exit(1)
105        break
106    ret = reader.Read()
107if ret != 1:
108    print "Error finding the ref element"
109    sys.exit(1)
110
111#
112# Home made example for the various attribute access functions
113#
114f = StringIO.StringIO("""<testattr xmlns="urn:1" xmlns:a="urn:2" b="b" a:b="a:b"/>""")
115input = libxml2.inputBuffer(f)
116reader = input.newTextReader("test4")
117ret = reader.Read()
118if ret != 1:
119    print "Error reading the testattr element"
120    sys.exit(1)
121#
122# Attribute exploration by index
123#
124if reader.MoveToAttributeNo(0) != 1:
125    print "Failed moveToAttribute(0)"
126    sys.exit(1)
127if reader.Value() != "urn:1":
128    print "Failed to read attribute(0)"
129    sys.exit(1)
130if reader.Name() != "xmlns":
131    print "Failed to read attribute(0) name"
132    sys.exit(1)
133if reader.MoveToAttributeNo(1) != 1:
134    print "Failed moveToAttribute(1)"
135    sys.exit(1)
136if reader.Value() != "urn:2":
137    print "Failed to read attribute(1)"
138    sys.exit(1)
139if reader.Name() != "xmlns:a":
140    print "Failed to read attribute(1) name"
141    sys.exit(1)
142if reader.MoveToAttributeNo(2) != 1:
143    print "Failed moveToAttribute(2)"
144    sys.exit(1)
145if reader.Value() != "b":
146    print "Failed to read attribute(2)"
147    sys.exit(1)
148if reader.Name() != "b":
149    print "Failed to read attribute(2) name"
150    sys.exit(1)
151if reader.MoveToAttributeNo(3) != 1:
152    print "Failed moveToAttribute(3)"
153    sys.exit(1)
154if reader.Value() != "a:b":
155    print "Failed to read attribute(3)"
156    sys.exit(1)
157if reader.Name() != "a:b":
158    print "Failed to read attribute(3) name"
159    sys.exit(1)
160#
161# Attribute exploration by name
162#
163if reader.MoveToAttribute("xmlns") != 1:
164    print "Failed moveToAttribute('xmlns')"
165    sys.exit(1)
166if reader.Value() != "urn:1":
167    print "Failed to read attribute('xmlns')"
168    sys.exit(1)
169if reader.MoveToAttribute("xmlns:a") != 1:
170    print "Failed moveToAttribute('xmlns')"
171    sys.exit(1)
172if reader.Value() != "urn:2":
173    print "Failed to read attribute('xmlns:a')"
174    sys.exit(1)
175if reader.MoveToAttribute("b") != 1:
176    print "Failed moveToAttribute('b')"
177    sys.exit(1)
178if reader.Value() != "b":
179    print "Failed to read attribute('b')"
180    sys.exit(1)
181if reader.MoveToAttribute("a:b") != 1:
182    print "Failed moveToAttribute('a:b')"
183    sys.exit(1)
184if reader.Value() != "a:b":
185    print "Failed to read attribute('a:b')"
186    sys.exit(1)
187if reader.MoveToAttributeNs("b", "urn:2") != 1:
188    print "Failed moveToAttribute('b', 'urn:2')"
189    sys.exit(1)
190if reader.Value() != "a:b":
191    print "Failed to read attribute('b', 'urn:2')"
192    sys.exit(1)
193#
194# Go back and read in sequence
195#
196if reader.MoveToElement() != 1:
197    print "Failed to move back to element"
198    sys.exit(1)
199if reader.MoveToFirstAttribute() != 1:
200    print "Failed to move to first attribute"
201    sys.exit(1)
202if reader.Value() != "urn:1":
203    print "Failed to read attribute(0)"
204    sys.exit(1)
205if reader.Name() != "xmlns":
206    print "Failed to read attribute(0) name"
207    sys.exit(1)
208if reader.MoveToNextAttribute() != 1:
209    print "Failed to move to next attribute"
210    sys.exit(1)
211if reader.Value() != "urn:2":
212    print "Failed to read attribute(1)"
213    sys.exit(1)
214if reader.Name() != "xmlns:a":
215    print "Failed to read attribute(1) name"
216    sys.exit(1)
217if reader.MoveToNextAttribute() != 1:
218    print "Failed to move to next attribute"
219    sys.exit(1)
220if reader.Value() != "b":
221    print "Failed to read attribute(2)"
222    sys.exit(1)
223if reader.Name() != "b":
224    print "Failed to read attribute(2) name"
225    sys.exit(1)
226if reader.MoveToNextAttribute() != 1:
227    print "Failed to move to next attribute"
228    sys.exit(1)
229if reader.Value() != "a:b":
230    print "Failed to read attribute(3)"
231    sys.exit(1)
232if reader.Name() != "a:b":
233    print "Failed to read attribute(3) name"
234    sys.exit(1)
235if reader.MoveToNextAttribute() != 0:
236    print "Failed to detect last attribute"
237    sys.exit(1)
238
239
240#
241# a couple of tests for namespace nodes
242#
243f = StringIO.StringIO("""<a xmlns="http://example.com/foo"/>""")
244input = libxml2.inputBuffer(f)
245reader = input.newTextReader("test6")
246ret = reader.Read()
247if ret != 1:
248    print "test6: failed to Read()"
249    sys.exit(1)
250ret = reader.MoveToFirstAttribute()
251if ret != 1:
252    print "test6: failed to MoveToFirstAttribute()"
253    sys.exit(1)
254if reader.NamespaceUri() != "http://www.w3.org/2000/xmlns/" or \
255   reader.LocalName() != "xmlns" or reader.Name() != "xmlns" or \
256   reader.Value() != "http://example.com/foo" or reader.NodeType() != 2:
257    print "test6: failed to read the namespace node"
258    sys.exit(1)
259
260f = StringIO.StringIO("""<a xmlns:prefix="http://example.com/foo"/>""")
261input = libxml2.inputBuffer(f)
262reader = input.newTextReader("test7")
263ret = reader.Read()
264if ret != 1:
265    print "test7: failed to Read()"
266    sys.exit(1)
267ret = reader.MoveToFirstAttribute()
268if ret != 1:
269    print "test7: failed to MoveToFirstAttribute()"
270    sys.exit(1)
271if reader.NamespaceUri() != "http://www.w3.org/2000/xmlns/" or \
272   reader.LocalName() != "prefix" or reader.Name() != "xmlns:prefix" or \
273   reader.Value() != "http://example.com/foo" or reader.NodeType() != 2:
274    print "test7: failed to read the namespace node"
275    sys.exit(1)
276
277#
278# Test for a limit case:
279#
280f = StringIO.StringIO("""<a/>""")
281input = libxml2.inputBuffer(f)
282reader = input.newTextReader("test8")
283ret = reader.Read()
284if ret != 1:
285    print "test8: failed to read the node"
286    sys.exit(1)
287if reader.Name() != "a" or reader.IsEmptyElement() != 1:
288    print "test8: failed to analyze the node"
289    sys.exit(1)
290ret = reader.Read()
291if ret != 0:
292    print "test8: failed to detect the EOF"
293    sys.exit(1)
294
295#
296# Another test provided by St�phane Bidoul and checked with C#
297#
298def tst_reader(s):
299    f = StringIO.StringIO(s)
300    input = libxml2.inputBuffer(f)
301    reader = input.newTextReader("tst")
302    res = ""
303    while reader.Read():
304        res=res + "%s (%s) [%s] %d %d\n" % (reader.NodeType(),reader.Name(),
305                                      reader.Value(), reader.IsEmptyElement(),
306                                      reader.Depth())
307        if reader.NodeType() == 1: # Element
308            while reader.MoveToNextAttribute():
309                res = res + "-- %s (%s) [%s] %d %d\n" % (reader.NodeType(),
310                                       reader.Name(),reader.Value(),
311                                       reader.IsEmptyElement(), reader.Depth())
312    return res
313
314doc="""<a><b b1="b1"/><c>content of c</c></a>"""
315expect="""1 (a) [None] 0 0
3161 (b) [None] 1 1
317-- 2 (b1) [b1] 0 2
3181 (c) [None] 0 1
3193 (#text) [content of c] 0 2
32015 (c) [None] 0 1
32115 (a) [None] 0 0
322"""
323res = tst_reader(doc)
324if res != expect:
325    print "test5 failed"
326    print res
327    sys.exit(1)
328
329doc="""<test><b/><c/></test>"""
330expect="""1 (test) [None] 0 0
3311 (b) [None] 1 1
3321 (c) [None] 1 1
33315 (test) [None] 0 0
334"""
335res = tst_reader(doc)
336if res != expect:
337    print "test9 failed"
338    print res
339    sys.exit(1)
340
341doc="""<a><b>bbb</b><c>ccc</c></a>"""
342expect="""1 (a) [None] 0 0
3431 (b) [None] 0 1
3443 (#text) [bbb] 0 2
34515 (b) [None] 0 1
3461 (c) [None] 0 1
3473 (#text) [ccc] 0 2
34815 (c) [None] 0 1
34915 (a) [None] 0 0
350"""
351res = tst_reader(doc)
352if res != expect:
353    print "test10 failed"
354    print res
355    sys.exit(1)
356
357doc="""<test a="a"/>"""
358expect="""1 (test) [None] 1 0
359-- 2 (a) [a] 0 1
360"""
361res = tst_reader(doc)
362if res != expect:
363    print "test11 failed"
364    print res
365    sys.exit(1)
366
367doc="""<test><a>aaa</a><b/></test>"""
368expect="""1 (test) [None] 0 0
3691 (a) [None] 0 1
3703 (#text) [aaa] 0 2
37115 (a) [None] 0 1
3721 (b) [None] 1 1
37315 (test) [None] 0 0
374"""
375res = tst_reader(doc)
376if res != expect:
377    print "test12 failed"
378    print res
379    sys.exit(1)
380
381doc="""<test><p></p></test>"""
382expect="""1 (test) [None] 0 0
3831 (p) [None] 0 1
38415 (p) [None] 0 1
38515 (test) [None] 0 0
386"""
387res = tst_reader(doc)
388if res != expect:
389    print "test13 failed"
390    print res
391    sys.exit(1)
392
393doc="""<p></p>"""
394expect="""1 (p) [None] 0 0
39515 (p) [None] 0 0
396"""
397res = tst_reader(doc)
398if res != expect:
399    print "test14 failed"
400    print res
401    sys.exit(1)
402
403#
404# test from bug #108801
405#
406doc="""<?xml version="1.0" standalone="no"?>
407<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
408                  "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
409]>
410
411<article>
412xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
413</article>
414"""
415expect="""10 (article) [None] 0 0
4161 (article) [None] 0 0
4173 (#text) [
418xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
419] 0 1
42015 (article) [None] 0 0
421"""
422res = tst_reader(doc)
423if res != expect:
424    print "test15 failed"
425    print res
426    sys.exit(1)
427
428#
429# cleanup for memory allocation counting
430#
431del f
432del input
433del reader
434
435# Memory debug specific
436libxml2.cleanupParser()
437if libxml2.debugMemory(1) == 0:
438    print "OK"
439else:
440    print "Memory leak %d bytes" % (libxml2.debugMemory(1))
441    libxml2.dumpMemory()
442