1   
  2   
  3   
  4   
  5   
  6   
  7  import sys 
  8   
  9  try: 
 10      from StringIO import StringIO 
 11      BytesIO = StringIO 
 12  except ImportError: 
 13      from io import BytesIO, StringIO 
 14   
 15  from lxml import etree as ElementTree 
 16   
 18      if sys.version_info[0] < 3: 
 19          return sys.stdout 
 20      class bytes_stdout(object): 
 21          def write(self, data): 
 22              if isinstance(data, bytes): 
 23                  data = data.decode('ISO8859-1') 
 24              sys.stdout.write(data) 
  25      return bytes_stdout() 
 26   
 31   
 33      file = BytesIO() 
 34      tree = ElementTree.ElementTree(elem) 
 35      if encoding: 
 36          tree.write(file, encoding=encoding) 
 37      else: 
 38          tree.write(file) 
 39      result = file.getvalue() 
 40      if sys.version_info[0] >= 3: 
 41          result = result.decode('ISO8859-1') 
 42      result = result.replace(' />', '/>') 
 43      if result[-1:] == '\n': 
 44          result = result[:-1] 
 45      return result 
  46   
 49   
 52   
 53  SAMPLE_XML = unserialize(""" 
 54  <body> 
 55    <tag>text</tag> 
 56    <tag /> 
 57    <section> 
 58      <tag>subtext</tag> 
 59    </section> 
 60  </body> 
 61  """) 
 62   
 63  SAMPLE_XML_NS = unserialize(""" 
 64  <body xmlns="http://effbot.org/ns"> 
 65    <tag>text</tag> 
 66    <tag /> 
 67    <section> 
 68      <tag>subtext</tag> 
 69    </section> 
 70  </body> 
 71  """) 
 72   
 73   
 74   
 76      len(string) 
 77      for char in string: 
 78          if len(char) != 1: 
 79              print("expected one-character string, got %r" % char) 
 80      new_string = string + "" 
 81      new_string = string + " " 
 82      string[:0] 
  83   
 85      len(mapping) 
 86      keys = mapping.keys() 
 87      items = mapping.items() 
 88      for key in keys: 
 89          item = mapping[key] 
 90      mapping["key"] = "value" 
 91      if mapping["key"] != "value": 
 92          print("expected value string, got %r" % mapping["key"]) 
  93   
109   
112   
114      """ 
115      Test element tree interface. 
116   
117      >>> element = ElementTree.Element("tag") 
118      >>> check_element(element) 
119      >>> tree = ElementTree.ElementTree(element) 
120      >>> check_element_tree(tree) 
121      """ 
 122   
124      """ 
125      Test parsing from file.  Note that we're opening the files in 
126      here; by default, the 'parse' function opens the file in binary 
127      mode, and doctest doesn't filter out carriage returns. 
128   
129      >>> file = open("samples/simple.xml", "rb") 
130      >>> tree = ElementTree.parse(file) 
131      >>> file.close() 
132      >>> tree.write(stdout()) 
133      <root> 
134         <element key="value">text</element> 
135         <element>text</element>tail 
136         <empty-element/> 
137      </root> 
138      >>> file = open("samples/simple-ns.xml", "rb") 
139      >>> tree = ElementTree.parse(file) 
140      >>> file.close() 
141      >>> tree.write(stdout()) 
142      <root xmlns="http://namespace/"> 
143         <element key="value">text</element> 
144         <element>text</element>tail 
145         <empty-element/> 
146      </root> 
147      """ 
 148   
150      """ 
151      >>> elem = ElementTree.Element("tag") 
152      >>> elem.text = "text" 
153      >>> serialize(elem) 
154      '<tag>text</tag>' 
155      >>> ElementTree.SubElement(elem, "subtag").text = "subtext" 
156      >>> serialize(elem) 
157      '<tag>text<subtag>subtext</subtag></tag>' 
158      """ 
 159   
161      r""" 
162      Test encoding issues. 
163   
164      >>> elem = ElementTree.Element("tag") 
165      >>> elem.text = u'abc' 
166      >>> serialize(elem) 
167      '<tag>abc</tag>' 
168      >>> serialize(elem, "utf-8") 
169      '<tag>abc</tag>' 
170      >>> serialize(elem, "us-ascii") 
171      '<tag>abc</tag>' 
172      >>> serialize(elem, "iso-8859-1").lower() 
173      "<?xml version='1.0' encoding='iso-8859-1'?>\n<tag>abc</tag>" 
174   
175      >>> elem.text = "<&\"\'>" 
176      >>> serialize(elem) 
177      '<tag><&"\'></tag>' 
178      >>> serialize(elem, "utf-8") 
179      '<tag><&"\'></tag>' 
180      >>> serialize(elem, "us-ascii") # cdata characters 
181      '<tag><&"\'></tag>' 
182      >>> serialize(elem, "iso-8859-1").lower() 
183      '<?xml version=\'1.0\' encoding=\'iso-8859-1\'?>\n<tag><&"\'></tag>' 
184   
185      >>> elem.attrib["key"] = "<&\"\'>" 
186      >>> elem.text = None 
187      >>> serialize(elem) 
188      '<tag key="<&"\'>"/>' 
189      >>> serialize(elem, "utf-8") 
190      '<tag key="<&"\'>"/>' 
191      >>> serialize(elem, "us-ascii") 
192      '<tag key="<&"\'>"/>' 
193      >>> serialize(elem, "iso-8859-1").lower() 
194      '<?xml version=\'1.0\' encoding=\'iso-8859-1\'?>\n<tag key="<&"\'>"/>' 
195   
196      >>> elem.text = u'\xe5\xf6\xf6<>' 
197      >>> elem.attrib.clear() 
198      >>> serialize(elem) 
199      '<tag>åöö<></tag>' 
200      >>> serialize(elem, "utf-8") 
201      '<tag>\xc3\xa5\xc3\xb6\xc3\xb6<></tag>' 
202      >>> serialize(elem, "us-ascii") 
203      '<tag>åöö<></tag>' 
204      >>> serialize(elem, "iso-8859-1").lower() 
205      "<?xml version='1.0' encoding='iso-8859-1'?>\n<tag>\xe5\xf6\xf6<></tag>" 
206   
207      >>> elem.attrib["key"] = u'\xe5\xf6\xf6<>' 
208      >>> elem.text = None 
209      >>> serialize(elem) 
210      '<tag key="åöö<>"/>' 
211      >>> serialize(elem, "utf-8") 
212      '<tag key="\xc3\xa5\xc3\xb6\xc3\xb6<>"/>' 
213      >>> serialize(elem, "us-ascii") 
214      '<tag key="åöö<>"/>' 
215      >>> serialize(elem, "iso-8859-1").lower() 
216      '<?xml version=\'1.0\' encoding=\'iso-8859-1\'?>\n<tag key="\xe5\xf6\xf6<>"/>' 
217   
218      """ 
 219   
220  if sys.version_info[0] >= 3: 
221      encoding.__doc__ = encoding.__doc__.replace("u'", "'") 
222   
224      """ 
225      Test QName handling. 
226   
227      1) decorated tags 
228   
229      >>> elem = ElementTree.Element("{uri}tag") 
230      >>> serialize(elem) # 1.1 
231      '<ns0:tag xmlns:ns0="uri"/>' 
232   
233  ##     2) decorated attributes 
234   
235  ##     >>> elem.attrib["{uri}key"] = "value" 
236  ##     >>> serialize(elem) # 2.1 
237  ##     '<ns0:tag ns0:key="value" xmlns:ns0="uri"/>' 
238   
239      """ 
 240   
242      """ 
243      Test CDATA handling (etc). 
244   
245      >>> serialize(unserialize("<tag>hello</tag>")) 
246      '<tag>hello</tag>' 
247      >>> serialize(unserialize("<tag>hello</tag>")) 
248      '<tag>hello</tag>' 
249      >>> serialize(unserialize("<tag><![CDATA[hello]]></tag>")) 
250      '<tag>hello</tag>' 
251   
252      """ 
 253   
255      """ 
256      Test find methods (including xpath syntax). 
257   
258      >>> elem = SAMPLE_XML 
259      >>> elem.find("tag").tag 
260      'tag' 
261      >>> ElementTree.ElementTree(elem).find("tag").tag 
262      'tag' 
263      >>> elem.find("section/tag").tag 
264      'tag' 
265      >>> ElementTree.ElementTree(elem).find("section/tag").tag 
266      'tag' 
267      >>> elem.findtext("tag") 
268      'text' 
269      >>> elem.findtext("tog", "default") 
270      'default' 
271      >>> ElementTree.ElementTree(elem).findtext("tag") 
272      'text' 
273      >>> elem.findtext("section/tag") 
274      'subtext' 
275      >>> ElementTree.ElementTree(elem).findtext("section/tag") 
276      'subtext' 
277      >>> summarize_list(elem.findall("tag")) 
278      ['tag', 'tag'] 
279      >>> summarize_list(elem.findall("*")) 
280      ['tag', 'tag', 'section'] 
281      >>> summarize_list(elem.findall(".//tag")) 
282      ['tag', 'tag', 'tag'] 
283      >>> summarize_list(elem.findall("section/tag")) 
284      ['tag'] 
285      >>> summarize_list(elem.findall("section//tag")) 
286      ['tag'] 
287      >>> summarize_list(elem.findall("section/*")) 
288      ['tag'] 
289      >>> summarize_list(elem.findall("section//*")) 
290      ['tag'] 
291      >>> summarize_list(elem.findall("section/.//*")) 
292      ['tag'] 
293      >>> summarize_list(elem.findall("*/*")) 
294      ['tag'] 
295      >>> summarize_list(elem.findall("*//*")) 
296      ['tag'] 
297      >>> summarize_list(elem.findall("*/tag")) 
298      ['tag'] 
299      >>> summarize_list(elem.findall("*/./tag")) 
300      ['tag'] 
301      >>> summarize_list(elem.findall("./tag")) 
302      ['tag', 'tag'] 
303      >>> summarize_list(elem.findall(".//tag")) 
304      ['tag', 'tag', 'tag'] 
305      >>> summarize_list(elem.findall("././tag")) 
306      ['tag', 'tag'] 
307      >>> summarize_list(ElementTree.ElementTree(elem).findall("/tag")) 
308      ['tag', 'tag'] 
309      >>> summarize_list(ElementTree.ElementTree(elem).findall("./tag")) 
310      ['tag', 'tag'] 
311      >>> elem = SAMPLE_XML_NS 
312      >>> summarize_list(elem.findall("tag")) 
313      [] 
314      >>> summarize_list(elem.findall("{http://effbot.org/ns}tag")) 
315      ['{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag'] 
316      >>> summarize_list(elem.findall(".//{http://effbot.org/ns}tag")) 
317      ['{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag'] 
318      """ 
 319   
320   
321   
323      """ 
324      Test copy handling (etc). 
325   
326      >>> import copy 
327      >>> e1 = unserialize("<tag>hello<foo/></tag>") 
328      >>> # e2 = copy.copy(e1) 
329      >>> e3 = copy.deepcopy(e1) 
330      >>> e1.find("foo").tag = "bar" 
331   
332      >>> serialize(e1).replace(' ', '') 
333      '<tag>hello<bar/></tag>' 
334   
335  ##     >>> serialize(e2).replace(' ', '') 
336  ##     '<tag>hello<bar/></tag>' 
337   
338      >>> serialize(e3).replace(' ', '') 
339      '<tag>hello<foo/></tag>' 
340   
341      """ 
 342   
344      """ 
345      Test attribute handling. 
346   
347      >>> elem = ElementTree.Element("tag") 
348      >>> elem.get("key") # 1.1 
349      >>> elem.get("key", "default") # 1.2 
350      'default' 
351      >>> elem.set("key", "value") 
352      >>> elem.get("key") # 1.3 
353      'value' 
354   
355      >>> elem = ElementTree.Element("tag", key="value") 
356      >>> elem.get("key") # 2.1 
357      'value' 
358      >>> elem.attrib # 2.2 
359      {'key': 'value'} 
360   
361      >>> elem = ElementTree.Element("tag", {"key": "value"}) 
362      >>> elem.get("key") # 3.1 
363      'value' 
364      >>> elem.attrib # 3.2 
365      {'key': 'value'} 
366   
367      >>> elem = ElementTree.Element("tag", {"key": "other"}, key="value") 
368      >>> elem.get("key") # 4.1 
369      'value' 
370      >>> elem.attrib # 4.2 
371      {'key': 'value'} 
372   
373      """ 
 374   
376      """ 
377      Test makeelement handling. 
378   
379      >>> elem = ElementTree.Element("tag") 
380      >>> subelem = elem.makeelement("subtag", {"key": "value"}) 
381      >>> elem.append(subelem) 
382      >>> serialize(elem) 
383      '<tag><subtag key="value"/></tag>' 
384   
385      >>> elem.clear() 
386      >>> serialize(elem) 
387      '<tag/>' 
388      >>> elem.append(subelem) 
389      >>> serialize(elem) 
390      '<tag><subtag key="value"/></tag>' 
391   
392      """ 
 393   
394   
395   
396   
397   
398   
399   
400   
401   
402   
403   
404   
405   
406   
407   
408   
409   
410   
411   
412   
413   
414   
415   
416   
417  ENTITY_XML = """\ 
418  <!DOCTYPE points [ 
419  <!ENTITY % user-entities SYSTEM 'user-entities.xml'> 
420  %user-entities; 
421  ]> 
422  <document>&entity;</document> 
423  """ 
424   
425   
426   
427   
428   
429   
430   
431   
432   
433   
434   
435   
436   
437   
438   
439   
440   
441   
442   
443   
444   
445   
446  if __name__ == "__main__": 
447      import doctest, selftest2 
448      failed, tested = doctest.testmod(selftest2) 
449      print("%d tests ok." % (tested - failed)) 
450      if failed > 0: 
451          print("%d tests failed. Exiting with non-zero return code." % failed) 
452          sys.exit(1) 
453