|
1 |
| -try: |
2 |
| - from xml.etree import ElementTree |
3 |
| -except ImportError: |
4 |
| - from elementtree import ElementTree |
| 1 | +import etreefull |
5 | 2 |
|
6 |
| -import _base |
7 |
| - |
8 |
| -class Element(_base.Node): |
9 |
| - def __init__(self, name): |
10 |
| - self._element = ElementTree.Element(name) |
11 |
| - self.name = name |
12 |
| - self.parent = None |
13 |
| - self._childNodes = [] |
14 |
| - self._flags = [] |
15 |
| - |
16 |
| - def _setName(self, name): |
17 |
| - self._element.tag = name |
18 |
| - |
19 |
| - def _getName(self): |
20 |
| - return self._element.tag |
21 |
| - |
22 |
| - name = property(_getName, _setName) |
23 |
| - |
24 |
| - def _getAttributes(self): |
25 |
| - return self._element.attrib |
26 |
| - |
27 |
| - def _setAttributes(self, attributes): |
28 |
| - #Delete existing attributes first |
29 |
| - #XXX - there may be a better way to do this... |
30 |
| - for key in self._element.attrib.keys(): |
31 |
| - del self._element.attrib[key] |
32 |
| - for key, value in attributes.iteritems(): |
33 |
| - self._element.set(key, value) |
34 |
| - |
35 |
| - attributes = property(_getAttributes, _setAttributes) |
36 |
| - |
37 |
| - def _getChildNodes(self): |
38 |
| - return self._childNodes |
39 |
| - |
40 |
| - def _setChildNodes(self, value): |
41 |
| - del self._element[:] |
42 |
| - self._childNodes = [] |
43 |
| - for element in value: |
44 |
| - self.insertChild(element) |
45 |
| - |
46 |
| - childNodes = property(_getChildNodes, _setChildNodes) |
47 |
| - |
48 |
| - def hasContent(self): |
49 |
| - """Return true if the node has children or text""" |
50 |
| - return bool(self._element.text or self._element.getchildren()) |
51 |
| - |
52 |
| - def appendChild(self, node): |
53 |
| - self._childNodes.append(node) |
54 |
| - self._element.append(node._element) |
55 |
| - node.parent = self |
56 |
| - |
57 |
| - def insertBefore(self, node, refNode): |
58 |
| - index = self._element.getchildren().index(refNode._element) |
59 |
| - self._element.insert(index, node._element) |
60 |
| - node.parent = self |
61 |
| - |
62 |
| - def removeChild(self, node): |
63 |
| - self._element.remove(node._element) |
64 |
| - node.parent=None |
65 |
| - |
66 |
| - def insertText(self, data, insertBefore=None): |
67 |
| - if not(len(self._element)): |
68 |
| - if not self._element.text: |
69 |
| - self._element.text = "" |
70 |
| - self._element.text += data |
71 |
| - elif insertBefore is None: |
72 |
| - #Insert the text as the tail of the last child element |
73 |
| - if not self._element[-1].tail: |
74 |
| - self._element[-1].tail = "" |
75 |
| - self._element[-1].tail += data |
76 |
| - else: |
77 |
| - #Insert the text before the specified node |
78 |
| - children = self._element.getchildren() |
79 |
| - index = children.index(insertBefore._element) |
80 |
| - if index > 0: |
81 |
| - if not self._element[index-1].tail: |
82 |
| - self._element[index-1].tail = "" |
83 |
| - self._element[index-1].tail += data |
84 |
| - else: |
85 |
| - if not self._element.text: |
86 |
| - self._element.text = "" |
87 |
| - self._element.text += data |
88 |
| - |
89 |
| - def cloneNode(self): |
90 |
| - element = Element(self.name) |
91 |
| - element.attributes = self.attributes |
92 |
| - return element |
93 |
| - |
94 |
| - def reparentChildren(self, newParent): |
95 |
| - if newParent.childNodes: |
96 |
| - newParent.childNodes[-1]._element.tail += self._element.text |
97 |
| - else: |
98 |
| - if not newParent._element.text: |
99 |
| - newParent._element.text = "" |
100 |
| - if self._element.text is not None: |
101 |
| - newParent._element.text += self._element.text |
102 |
| - self._element.text = "" |
103 |
| - _base.Node.reparentChildren(self, newParent) |
104 |
| - |
105 |
| -class Comment(Element): |
106 |
| - def __init__(self, data): |
107 |
| - #Use the superclass constructor to set all properties on the |
108 |
| - #wrapper element |
109 |
| - Element.__init__(self, None) |
110 |
| - self._element = ElementTree.Comment(data) |
111 |
| - |
112 |
| - def _getData(self): |
113 |
| - return self._element.text |
114 |
| - |
115 |
| - def _setData(self, value): |
116 |
| - self._element.text = value |
117 |
| - |
118 |
| - data = property(_getData, _setData) |
119 |
| - |
120 |
| -class DocumentType(Element): |
121 |
| - def __init__(self, name): |
122 |
| - Element.__init__(self, DocumentType) |
123 |
| - self._element.text = name |
124 |
| - |
125 |
| -class Document(Element): |
126 |
| - def __init__(self): |
127 |
| - Element.__init__(self, Document) |
128 |
| - |
129 |
| -def testSerializer(element): |
130 |
| - rv = [] |
131 |
| - finalText = None |
132 |
| - def serializeElement(element, indent=0): |
133 |
| - if element.tag is DocumentType: |
134 |
| - rv.append("|%s<!DOCTYPE %s>"%(' '*indent, element.text)) |
135 |
| - elif element.tag is Document: |
136 |
| - rv.append("#document") |
137 |
| - if element.text: |
138 |
| - rv.append("|%s\"%s\""%(' '*(indent+2), element.text)) |
139 |
| - if element.tail: |
140 |
| - finalText = element.tail |
141 |
| - elif element.tag is ElementTree.Comment: |
142 |
| - rv.append("|%s<!-- %s -->"%(' '*indent, element.text)) |
143 |
| - else: |
144 |
| - rv.append("|%s<%s>"%(' '*indent, element.tag)) |
145 |
| - if hasattr(element, "attrib"): |
146 |
| - for name, value in element.attrib.iteritems(): |
147 |
| - rv.append('|%s%s="%s"' % (' '*(indent+2), name, value)) |
148 |
| - if element.text: |
149 |
| - rv.append("|%s\"%s\"" %(' '*(indent+2), element.text)) |
150 |
| - indent += 2 |
151 |
| - for child in element.getchildren(): |
152 |
| - serializeElement(child, indent) |
153 |
| - if element.tail: |
154 |
| - rv.append("|%s\"%s\"" %(' '*(indent-2), element.tail)) |
155 |
| - serializeElement(element, 0) |
156 |
| - |
157 |
| - if finalText is not None: |
158 |
| - rv.append("|%s\"%s\""%(' '*2, finalText)) |
159 |
| - |
160 |
| - return "\n".join(rv) |
161 |
| - |
162 |
| -def tostring(element): |
163 |
| - """Serialize an element and its child nodes to a string""" |
164 |
| - rv = [] |
165 |
| - finalText = None |
166 |
| - def serializeElement(element): |
167 |
| - if element.tag is DocumentType: |
168 |
| - rv.append("<!DOCTYPE %s>"%(element.text,)) |
169 |
| - elif element.tag is Document: |
170 |
| - if element.text: |
171 |
| - rv.append(element.text) |
172 |
| - if element.tail: |
173 |
| - finalText = element.tail |
174 |
| - |
175 |
| - for child in element.getchildren(): |
176 |
| - serializeElement(child) |
177 |
| - |
178 |
| - elif element.tag is ElementTree.Comment: |
179 |
| - rv.append("<!--%s-->"%(element.text,)) |
180 |
| - else: |
181 |
| - #This is assumed to be an ordinary element |
182 |
| - if not element.attrib: |
183 |
| - rv.append("<%s>"%(element.tag,)) |
184 |
| - else: |
185 |
| - attr = " ".join(["%s=\"%s\""%(name, value) |
186 |
| - for name, value in element.attrib.iteritems()]) |
187 |
| - rv.append("<%s %s>"%(element.tag, attr)) |
188 |
| - if element.text: |
189 |
| - rv.append(element.text) |
190 |
| - |
191 |
| - for child in element.getchildren(): |
192 |
| - serializeElement(child) |
193 |
| - |
194 |
| - rv.append("</%s>"%(element.tag,)) |
195 |
| - |
196 |
| - if element.tail: |
197 |
| - rv.append(element.tail) |
198 |
| - |
199 |
| - serializeElement(element) |
200 |
| - |
201 |
| - if finalText is not None: |
202 |
| - rv.append("%s\""%(' '*2, finalText)) |
203 |
| - |
204 |
| - return "".join(rv) |
205 |
| - |
206 |
| -class TreeBuilderFull(_base.TreeBuilder): |
207 |
| - documentClass = Document |
208 |
| - doctypeClass = DocumentType |
209 |
| - elementClass = Element |
210 |
| - commentClass = Comment |
211 |
| - |
212 |
| - def testSerializer(self, element): |
213 |
| - return testSerializer(element) |
214 |
| - |
215 |
| - def getDocument(self): |
216 |
| - return self.document._element |
217 |
| - |
218 |
| -class TreeBuilder(TreeBuilderFull): |
| 3 | +class TreeBuilder(etreefull.TreeBuilder): |
219 | 4 | def getDocument(self):
|
220 | 5 | return self.document._element.find("html")
|
0 commit comments