Initial checkin
[ejpi] / src / libraries / recipes / xml_utils.py
1 #!/usr/bin/env python
2
3
4 from __future__ import with_statement
5
6
7 def flatten(elem, includeTail = False):
8         """
9         Recursively extract text content.
10
11         @note To get rid of all subelements to a given element, and keep just the text, you can do:
12                 elem.text = flatten(elem); del elem[:]
13         """
14         text = elem.text or ""
15         for e in elem:
16                 text += flatten(e)
17                 if includeTail and e.tail:
18                         text += e.tail
19         return text
20
21
22 def append(elem, item):
23         """
24         Universal append to an Element
25         @param elem ElementTree.Element
26         @param item Either None, Str/Unicode, or ElementTree.Element
27         """
28         if item is None:
29                 return
30
31         if isinstance(item, basestring):
32                 if len(elem):
33                         elem[-1].tail = (elem[-1].tail or "") + item
34                 else:
35                         elem.text = (elem.text or "") + item
36         else:
37                 elem.append(item)
38
39
40 def indent(elem, level=0, indentation="    "):
41         """
42         Add indentation to the data of in an ElementTree
43
44         >>> from xml.etree import ElementTree
45         >>> xmlRoot = ElementTree.fromstring("<xml><tree><bird /></tree></xml>")
46         >>> indent(xmlRoot)
47         >>> ElementTree.dump(xmlRoot)
48         <xml>
49             <tree>
50                 <bird />
51             </tree>
52         </xml>
53         """
54
55         i = "\n" + level*indentation
56         if len(elem):
57                 if not elem.text or not elem.text.strip():
58                         elem.text = i + indentation
59                 for e in elem:
60                         indent(e, level+1, indentation)
61                         if not e.tail or not e.tail.strip():
62                                 e.tail = i + indentation
63                         if not e.tail or not e.tail.strip():
64                                 e.tail = i
65         else:
66                 if level and (not elem.tail or not elem.tail.strip()):
67                         elem.tail = i
68
69
70 if __name__ == "__main__":
71         import sys
72         from xml.etree import ElementTree
73         if len(sys.argv) == 3:
74                 xml = ElementTree.parse(sys.argv[1])
75                 indent(xml.getroot())
76                 with open(sys.argv[2], "w") as source:
77                         xml.write(source)
78         elif len(sys.argv) == 1:
79                 xml = ElementTree.parse(sys.stdin)
80                 indent(xml.getroot())
81                 xml.write(sys.stdout)