1 import xml.etree.ElementTree
3 class Element(xml.etree.ElementTree._Element_Py):
4 def __init__(self, tag = 'Element', attrib = {}, text = '', children = []):
5 xml.etree.ElementTree._Element_Py.__init__(self, tag, attrib)
8 set_text(self, 0, text)
10 def serialize(self, ref_list):
12 # parented, enforce that child can only be parented at most once
13 # (although there can be unlimited numbers of numeric refs to it)
18 def deserialize(self, ref_list):
20 i.deserialize(ref_list)
21 def copy(self, factory = None):
22 result = (Element if factory is None else factory)(self.tag, self.attrib)
23 result.text = self.text
24 result.tail = self.tail
25 result[:] = [i.copy() for i in self]
27 def repr_serialize(self, params):
30 'children = [{0:s}]'.format(
31 ', '.join([repr(i) for i in self])
36 self.repr_serialize(params)
37 return 'element.Element({0:s})'.format(', '.join(params))
39 bool_to_str = ['false', 'true']
40 def serialize_bool(value):
41 return bool_to_str[int(value)]
43 str_to_bool = {'false': False, 'true': True}
44 def deserialize_bool(text):
45 return str_to_bool[text]
47 def serialize_int(value):
50 def deserialize_int(text):
53 def serialize_ref(value, ref_list):
60 ref_list.append(value)
62 value.set('ref', str(ref))
63 # this doesn't set the seen flag, so it will be parented by the
64 # root, unless it is already parented or gets parented later on
66 value.serialize(ref_list)
69 def deserialize_ref(text, ref_list):
71 return None if ref < 0 else ref_list[ref]
73 def serialize_str(value):
76 def deserialize_str(text):
79 def serialize(value, fout, encoding = 'unicode'):
81 serialize_ref(value, ref_list)
82 parents = [i for i in ref_list if not i.seen]
83 root = Element('root', children = parents)
84 for i in range(len(root)):
85 set_text(root, i, '\n ')
86 set_text(root, len(root), '\n')
88 xml.etree.ElementTree.ElementTree(root).write(fout, encoding)
95 while i < len(parents):
101 def deserialize(fin, factory = Element, encoding = 'unicode'):
102 root = xml.etree.ElementTree.parse(
104 xml.etree.ElementTree.XMLParser(
105 target = xml.etree.ElementTree.TreeBuilder(factory),
109 assert root.tag == 'root'
115 while i < len(parents):
117 if 'ref' in j.attrib:
118 ref = int(j.attrib['ref'])
120 if len(ref_list) < ref + 1:
121 ref_list.extend([None] * (ref + 1 - len(ref_list)))
126 i.deserialize(ref_list)
129 # compatibility scheme to access arbitrary xml.etree.ElementTree.Element-like
130 # objects (not just Element defined above) using a more consistent interface:
131 def get_text(root, i):
134 text = root.text if i == 0 else root[i - 1].tail
135 return '' if text is None else text
137 def set_text(root, i, text):
145 root[i - 1].tail = text
147 def to_end_relative(root, pos, off):
148 assert pos >= 0 and off >= 0
149 off -= len(get_text(root, pos))
153 def to_start_relative(root, pos, off):
154 assert pos < 0 and off <= 0
156 off += len(get_text(root, pos))