/Lib/test/test_xml_etree.py

http://unladen-swallow.googlecode.com/ · Python · 355 lines · 290 code · 29 blank · 36 comment · 7 complexity · 4d202e1018e71bbf89830012f47b22b6 MD5 · raw file

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