Issue #7051: Clarify behaviour of 'g' and 'G'-style formatting.
[python.git] / Lib / test / test_xml_etree.py
blob65c99f1327548e14f3c98ab7cbaf7f5d1d9e0b15
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.
5 import doctest
6 import sys
8 from test import test_support
10 SAMPLE_XML = """
11 <body>
12 <tag>text</tag>
13 <tag />
14 <section>
15 <tag>subtext</tag>
16 </section>
17 </body>
18 """
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 """
30 def sanity():
31 """
32 Import sanity.
34 >>> from xml.etree import ElementTree
35 >>> from xml.etree import ElementInclude
36 >>> from xml.etree import ElementPath
37 """
39 def check_method(method):
40 if not callable(method):
41 print method, "not callable"
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()
53 def summarize(elem):
54 return elem.tag
56 def summarize_list(seq):
57 return map(summarize, seq)
59 def interface():
60 """
61 Test element tree interface.
63 >>> from xml.etree import ElementTree as ET
65 >>> element = ET.Element("tag", key="value")
66 >>> tree = ET.ElementTree(element)
68 Make sure all standard element methods exist.
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)
84 Basic method sanity checks.
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" />'
108 def find():
110 Test find methods (including xpath syntax).
112 >>> from xml.etree import ElementTree as ET
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"))
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']
177 def parseliteral():
178 r"""
180 >>> from xml.etree import ElementTree as ET
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)
196 >>> _, ids = ET.XMLID("<html><body id='body'>text</body></html>")
197 >>> len(ids)
199 >>> ids["body"].tag
200 'body'
204 def check_encoding(ET, encoding):
206 >>> from xml.etree import ElementTree as ET
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")
215 ET.XML("<?xml version='1.0' encoding='%s'?><xml />" % encoding)
219 # xinclude tests (samples from appendix C of the xinclude specification)
221 XINCLUDE = {}
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>
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>
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>
248 XINCLUDE["count.txt"] = "324387"
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>
258 XINCLUDE["data.xml"] = """\
259 <?xml version='1.0'?>
260 <data>
261 <item><![CDATA[Brooks & Shields]]></item>
262 </data>
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>
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>
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
296 def xinclude():
297 r"""
298 Basic inclusion example (XInclude C.1)
300 >>> from xml.etree import ElementTree as ET
301 >>> from xml.etree import ElementInclude
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>
315 Textual inclusion example (XInclude C.2)
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>
325 Textual inclusion of XML example (XInclude C.3)
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>&lt;?xml version='1.0'?&gt;
333 &lt;data&gt;
334 &lt;item&gt;&lt;![CDATA[Brooks &amp; Shields]]&gt;&lt;/item&gt;
335 &lt;/data&gt;
336 </example>
337 </document>
339 Fallback example (XInclude C.5)
340 Note! Fallback support is not yet implemented
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
350 def test_main():
351 from test import test_xml_etree
352 test_support.run_doctest(test_xml_etree, verbosity=True)
354 if __name__ == '__main__':
355 test_main()