|
1 # xml.etree test. This file contains enough tests to make sure that |
|
2 # all included components work as they should. For a more extensive |
|
3 # test suite, see the selftest script in the ElementTree distribution. |
|
4 |
|
5 import doctest |
|
6 import sys |
|
7 |
|
8 from test import test_support |
|
9 |
|
10 SAMPLE_XML = """ |
|
11 <body> |
|
12 <tag>text</tag> |
|
13 <tag /> |
|
14 <section> |
|
15 <tag>subtext</tag> |
|
16 </section> |
|
17 </body> |
|
18 """ |
|
19 |
|
20 SAMPLE_XML_NS = """ |
|
21 <body xmlns="http://effbot.org/ns"> |
|
22 <tag>text</tag> |
|
23 <tag /> |
|
24 <section> |
|
25 <tag>subtext</tag> |
|
26 </section> |
|
27 </body> |
|
28 """ |
|
29 |
|
30 def sanity(): |
|
31 """ |
|
32 Import sanity. |
|
33 |
|
34 >>> from xml.etree import ElementTree |
|
35 >>> from xml.etree import ElementInclude |
|
36 >>> from xml.etree import ElementPath |
|
37 """ |
|
38 |
|
39 def check_method(method): |
|
40 if not callable(method): |
|
41 print method, "not callable" |
|
42 |
|
43 def serialize(ET, elem, encoding=None): |
|
44 import StringIO |
|
45 file = StringIO.StringIO() |
|
46 tree = ET.ElementTree(elem) |
|
47 if encoding: |
|
48 tree.write(file, encoding) |
|
49 else: |
|
50 tree.write(file) |
|
51 return file.getvalue() |
|
52 |
|
53 def summarize(elem): |
|
54 return elem.tag |
|
55 |
|
56 def summarize_list(seq): |
|
57 return map(summarize, seq) |
|
58 |
|
59 def interface(): |
|
60 """ |
|
61 Test element tree interface. |
|
62 |
|
63 >>> from xml.etree import ElementTree as ET |
|
64 |
|
65 >>> element = ET.Element("tag", key="value") |
|
66 >>> tree = ET.ElementTree(element) |
|
67 |
|
68 Make sure all standard element methods exist. |
|
69 |
|
70 >>> check_method(element.append) |
|
71 >>> check_method(element.insert) |
|
72 >>> check_method(element.remove) |
|
73 >>> check_method(element.getchildren) |
|
74 >>> check_method(element.find) |
|
75 >>> check_method(element.findall) |
|
76 >>> check_method(element.findtext) |
|
77 >>> check_method(element.clear) |
|
78 >>> check_method(element.get) |
|
79 >>> check_method(element.set) |
|
80 >>> check_method(element.keys) |
|
81 >>> check_method(element.items) |
|
82 >>> check_method(element.getiterator) |
|
83 |
|
84 Basic method sanity checks. |
|
85 |
|
86 >>> serialize(ET, element) # 1 |
|
87 '<tag key="value" />' |
|
88 >>> subelement = ET.Element("subtag") |
|
89 >>> element.append(subelement) |
|
90 >>> serialize(ET, element) # 2 |
|
91 '<tag key="value"><subtag /></tag>' |
|
92 >>> element.insert(0, subelement) |
|
93 >>> serialize(ET, element) # 3 |
|
94 '<tag key="value"><subtag /><subtag /></tag>' |
|
95 >>> element.remove(subelement) |
|
96 >>> serialize(ET, element) # 4 |
|
97 '<tag key="value"><subtag /></tag>' |
|
98 >>> element.remove(subelement) |
|
99 >>> serialize(ET, element) # 5 |
|
100 '<tag key="value" />' |
|
101 >>> element.remove(subelement) |
|
102 Traceback (most recent call last): |
|
103 ValueError: list.remove(x): x not in list |
|
104 >>> serialize(ET, element) # 6 |
|
105 '<tag key="value" />' |
|
106 """ |
|
107 |
|
108 def find(): |
|
109 """ |
|
110 Test find methods (including xpath syntax). |
|
111 |
|
112 >>> from xml.etree import ElementTree as ET |
|
113 |
|
114 >>> elem = ET.XML(SAMPLE_XML) |
|
115 >>> elem.find("tag").tag |
|
116 'tag' |
|
117 >>> ET.ElementTree(elem).find("tag").tag |
|
118 'tag' |
|
119 >>> elem.find("section/tag").tag |
|
120 'tag' |
|
121 >>> ET.ElementTree(elem).find("section/tag").tag |
|
122 'tag' |
|
123 >>> elem.findtext("tag") |
|
124 'text' |
|
125 >>> elem.findtext("tog") |
|
126 >>> elem.findtext("tog", "default") |
|
127 'default' |
|
128 >>> ET.ElementTree(elem).findtext("tag") |
|
129 'text' |
|
130 >>> elem.findtext("section/tag") |
|
131 'subtext' |
|
132 >>> ET.ElementTree(elem).findtext("section/tag") |
|
133 'subtext' |
|
134 >>> summarize_list(elem.findall("tag")) |
|
135 ['tag', 'tag'] |
|
136 >>> summarize_list(elem.findall("*")) |
|
137 ['tag', 'tag', 'section'] |
|
138 >>> summarize_list(elem.findall(".//tag")) |
|
139 ['tag', 'tag', 'tag'] |
|
140 >>> summarize_list(elem.findall("section/tag")) |
|
141 ['tag'] |
|
142 >>> summarize_list(elem.findall("section//tag")) |
|
143 ['tag'] |
|
144 >>> summarize_list(elem.findall("section/*")) |
|
145 ['tag'] |
|
146 >>> summarize_list(elem.findall("section//*")) |
|
147 ['tag'] |
|
148 >>> summarize_list(elem.findall("section/.//*")) |
|
149 ['tag'] |
|
150 >>> summarize_list(elem.findall("*/*")) |
|
151 ['tag'] |
|
152 >>> summarize_list(elem.findall("*//*")) |
|
153 ['tag'] |
|
154 >>> summarize_list(elem.findall("*/tag")) |
|
155 ['tag'] |
|
156 >>> summarize_list(elem.findall("*/./tag")) |
|
157 ['tag'] |
|
158 >>> summarize_list(elem.findall("./tag")) |
|
159 ['tag', 'tag'] |
|
160 >>> summarize_list(elem.findall(".//tag")) |
|
161 ['tag', 'tag', 'tag'] |
|
162 >>> summarize_list(elem.findall("././tag")) |
|
163 ['tag', 'tag'] |
|
164 >>> summarize_list(ET.ElementTree(elem).findall("/tag")) |
|
165 ['tag', 'tag'] |
|
166 >>> summarize_list(ET.ElementTree(elem).findall("./tag")) |
|
167 ['tag', 'tag'] |
|
168 >>> elem = ET.XML(SAMPLE_XML_NS) |
|
169 >>> summarize_list(elem.findall("tag")) |
|
170 [] |
|
171 >>> summarize_list(elem.findall("{http://effbot.org/ns}tag")) |
|
172 ['{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag'] |
|
173 >>> summarize_list(elem.findall(".//{http://effbot.org/ns}tag")) |
|
174 ['{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag'] |
|
175 """ |
|
176 |
|
177 def parseliteral(): |
|
178 r""" |
|
179 |
|
180 >>> from xml.etree import ElementTree as ET |
|
181 |
|
182 >>> element = ET.XML("<html><body>text</body></html>") |
|
183 >>> ET.ElementTree(element).write(sys.stdout) |
|
184 <html><body>text</body></html> |
|
185 >>> element = ET.fromstring("<html><body>text</body></html>") |
|
186 >>> ET.ElementTree(element).write(sys.stdout) |
|
187 <html><body>text</body></html> |
|
188 >>> print ET.tostring(element) |
|
189 <html><body>text</body></html> |
|
190 >>> print ET.tostring(element, "ascii") |
|
191 <?xml version='1.0' encoding='ascii'?> |
|
192 <html><body>text</body></html> |
|
193 >>> _, ids = ET.XMLID("<html><body>text</body></html>") |
|
194 >>> len(ids) |
|
195 0 |
|
196 >>> _, ids = ET.XMLID("<html><body id='body'>text</body></html>") |
|
197 >>> len(ids) |
|
198 1 |
|
199 >>> ids["body"].tag |
|
200 'body' |
|
201 """ |
|
202 |
|
203 |
|
204 def check_encoding(ET, encoding): |
|
205 """ |
|
206 >>> from xml.etree import ElementTree as ET |
|
207 |
|
208 >>> check_encoding(ET, "ascii") |
|
209 >>> check_encoding(ET, "us-ascii") |
|
210 >>> check_encoding(ET, "iso-8859-1") |
|
211 >>> check_encoding(ET, "iso-8859-15") |
|
212 >>> check_encoding(ET, "cp437") |
|
213 >>> check_encoding(ET, "mac-roman") |
|
214 """ |
|
215 ET.XML("<?xml version='1.0' encoding='%s'?><xml />" % encoding) |
|
216 |
|
217 |
|
218 # |
|
219 # xinclude tests (samples from appendix C of the xinclude specification) |
|
220 |
|
221 XINCLUDE = {} |
|
222 |
|
223 XINCLUDE["C1.xml"] = """\ |
|
224 <?xml version='1.0'?> |
|
225 <document xmlns:xi="http://www.w3.org/2001/XInclude"> |
|
226 <p>120 Mz is adequate for an average home user.</p> |
|
227 <xi:include href="disclaimer.xml"/> |
|
228 </document> |
|
229 """ |
|
230 |
|
231 XINCLUDE["disclaimer.xml"] = """\ |
|
232 <?xml version='1.0'?> |
|
233 <disclaimer> |
|
234 <p>The opinions represented herein represent those of the individual |
|
235 and should not be interpreted as official policy endorsed by this |
|
236 organization.</p> |
|
237 </disclaimer> |
|
238 """ |
|
239 |
|
240 XINCLUDE["C2.xml"] = """\ |
|
241 <?xml version='1.0'?> |
|
242 <document xmlns:xi="http://www.w3.org/2001/XInclude"> |
|
243 <p>This document has been accessed |
|
244 <xi:include href="count.txt" parse="text"/> times.</p> |
|
245 </document> |
|
246 """ |
|
247 |
|
248 XINCLUDE["count.txt"] = "324387" |
|
249 |
|
250 XINCLUDE["C3.xml"] = """\ |
|
251 <?xml version='1.0'?> |
|
252 <document xmlns:xi="http://www.w3.org/2001/XInclude"> |
|
253 <p>The following is the source of the "data.xml" resource:</p> |
|
254 <example><xi:include href="data.xml" parse="text"/></example> |
|
255 </document> |
|
256 """ |
|
257 |
|
258 XINCLUDE["data.xml"] = """\ |
|
259 <?xml version='1.0'?> |
|
260 <data> |
|
261 <item><![CDATA[Brooks & Shields]]></item> |
|
262 </data> |
|
263 """ |
|
264 |
|
265 XINCLUDE["C5.xml"] = """\ |
|
266 <?xml version='1.0'?> |
|
267 <div xmlns:xi="http://www.w3.org/2001/XInclude"> |
|
268 <xi:include href="example.txt" parse="text"> |
|
269 <xi:fallback> |
|
270 <xi:include href="fallback-example.txt" parse="text"> |
|
271 <xi:fallback><a href="mailto:bob@example.org">Report error</a></xi:fallback> |
|
272 </xi:include> |
|
273 </xi:fallback> |
|
274 </xi:include> |
|
275 </div> |
|
276 """ |
|
277 |
|
278 XINCLUDE["default.xml"] = """\ |
|
279 <?xml version='1.0'?> |
|
280 <document xmlns:xi="http://www.w3.org/2001/XInclude"> |
|
281 <p>Example.</p> |
|
282 <xi:include href="samples/simple.xml"/> |
|
283 </document> |
|
284 """ |
|
285 |
|
286 def xinclude_loader(href, parse="xml", encoding=None): |
|
287 try: |
|
288 data = XINCLUDE[href] |
|
289 except KeyError: |
|
290 raise IOError("resource not found") |
|
291 if parse == "xml": |
|
292 from xml.etree.ElementTree import XML |
|
293 return XML(data) |
|
294 return data |
|
295 |
|
296 def xinclude(): |
|
297 r""" |
|
298 Basic inclusion example (XInclude C.1) |
|
299 |
|
300 >>> from xml.etree import ElementTree as ET |
|
301 >>> from xml.etree import ElementInclude |
|
302 |
|
303 >>> document = xinclude_loader("C1.xml") |
|
304 >>> ElementInclude.include(document, xinclude_loader) |
|
305 >>> print serialize(ET, document) # C1 |
|
306 <document> |
|
307 <p>120 Mz is adequate for an average home user.</p> |
|
308 <disclaimer> |
|
309 <p>The opinions represented herein represent those of the individual |
|
310 and should not be interpreted as official policy endorsed by this |
|
311 organization.</p> |
|
312 </disclaimer> |
|
313 </document> |
|
314 |
|
315 Textual inclusion example (XInclude C.2) |
|
316 |
|
317 >>> document = xinclude_loader("C2.xml") |
|
318 >>> ElementInclude.include(document, xinclude_loader) |
|
319 >>> print serialize(ET, document) # C2 |
|
320 <document> |
|
321 <p>This document has been accessed |
|
322 324387 times.</p> |
|
323 </document> |
|
324 |
|
325 Textual inclusion of XML example (XInclude C.3) |
|
326 |
|
327 >>> document = xinclude_loader("C3.xml") |
|
328 >>> ElementInclude.include(document, xinclude_loader) |
|
329 >>> print serialize(ET, document) # C3 |
|
330 <document> |
|
331 <p>The following is the source of the "data.xml" resource:</p> |
|
332 <example><?xml version='1.0'?> |
|
333 <data> |
|
334 <item><![CDATA[Brooks & Shields]]></item> |
|
335 </data> |
|
336 </example> |
|
337 </document> |
|
338 |
|
339 Fallback example (XInclude C.5) |
|
340 Note! Fallback support is not yet implemented |
|
341 |
|
342 >>> document = xinclude_loader("C5.xml") |
|
343 >>> ElementInclude.include(document, xinclude_loader) |
|
344 Traceback (most recent call last): |
|
345 IOError: resource not found |
|
346 >>> # print serialize(ET, document) # C5 |
|
347 |
|
348 """ |
|
349 |
|
350 def test_main(): |
|
351 from test import test_xml_etree |
|
352 test_support.run_doctest(test_xml_etree, verbosity=True) |
|
353 |
|
354 if __name__ == '__main__': |
|
355 test_main() |