1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
|
# This file (node.py) gets copied in several of my projects. Find out a way
# to avoid making duplicate copies in each of my projects.
import sys
class NodeType:
# unknown node type.
Unknown = 0
# the document root - typically has only one child element, but it can
# have multiple children.
Root = 1
# node that has name and attributes, and may have child nodes.
Element = 2
# node that only has textural content.
Content = 3
class NodeBase:
def __init__ (self, nodeType = NodeType.Unknown):
self.parent = None
self.nodeType = nodeType
self.__children = []
self.__hasContent = False
def appendChild (self, node):
self.__children.append(node)
node.parent = self
def appendElement (self, name):
node = Element(name)
self.appendChild(node)
return node
def hasContent (self):
return self.__hasContent
def appendContent (self, text):
node = Content(text)
self.appendChild(node)
self.__hasContent = True
return node
def firstChild (self):
return self.__children[0]
def setChildNodes (self, children):
self.__children = children
def getChildNodes (self):
return self.__children
def firstChildByName (self, name):
for child in self.__children:
if child.nodeType == NodeType.Element and child.name == name:
return child
return None
def getChildByName (self, name):
children = []
for child in self.__children:
if child.nodeType == NodeType.Element and child.name == name:
children.append(child)
return children
class Root(NodeBase):
def __init__ (self):
NodeBase.__init__(self, NodeType.Root)
class Content(NodeBase):
def __init__ (self, content):
NodeBase.__init__(self, NodeType.Content)
self.content = content
class Element(NodeBase):
def __init__ (self, name, attrs=None):
NodeBase.__init__(self, NodeType.Element)
self.name = name
self.attrs = attrs
if self.attrs == None:
self.attrs = {}
def getContent (self):
text = ''
first = True
for child in self.getChildNodes():
if first:
first = False
else:
text += ' '
if child.nodeType == NodeType.Content:
text += child.content
elif child.nodeType == NodeType.Element:
text += child.getContent()
return text
def getAttr (self, name):
if not self.attrs.has_key(name):
return None
return self.attrs[name]
def setAttr (self, name, val):
self.attrs[name] = val
def hasAttr (self, name):
return self.attrs.has_key(name)
encodeTable = {
'>': 'gt',
'<': 'lt',
'&': 'amp',
'"': 'quot',
'\'': 'apos'
}
def encodeString (sin):
sout = ''
for c in sin:
if ord(c) >= 128:
# encode non-ascii ranges.
sout += "\\x%2.2x"%ord(c)
elif encodeTable.has_key(c):
# encode html symbols.
sout += '&' + encodeTable[c] + ';'
else:
sout += c
return sout
def convertAttrValue (val):
if type(val) == type(True):
if val:
val = "true"
else:
val = "false"
elif type(val) == type(0):
val = "%d"%val
elif type(val) == type(0.0):
val = "%g"%val
return val
def prettyPrint (fd, node):
printNode(fd, node, 0, True)
def printNode (fd, node, level, breakLine):
singleIndent = ''
lf = ''
if breakLine:
singleIndent = ' '*4
lf = "\n"
indent = singleIndent*level
if node.nodeType == NodeType.Root:
# root node itself only contains child nodes.
for child in node.getChildNodes():
printNode(fd, child, level, True)
elif node.nodeType == NodeType.Element:
hasChildren = len(node.getChildNodes()) > 0
# We add '<' and '>' (or '/>') after the element content gets
# encoded.
line = node.name
if len(node.attrs) > 0:
keys = node.attrs.keys()
keys.sort()
for key in keys:
val = node.attrs[key]
if val == None:
continue
val = convertAttrValue(val)
line += " " + key + '="' + encodeString(val) + '"'
if hasChildren:
breakChildren = breakLine and not node.hasContent()
line = "<%s>"%line
if breakChildren:
line += "\n"
fd.write (indent + line)
for child in node.getChildNodes():
printNode(fd, child, level+1, breakChildren)
line = "</%s>%s"%(node.name, lf)
if breakChildren:
line = indent + line
fd.write (line)
else:
line = "<%s/>%s"%(line, lf)
fd.write (indent + line)
elif node.nodeType == NodeType.Content:
content = node.content
content = encodeString(content)
if len(content) > 0:
fd.write (indent + content + lf)
|