Commit | Line | Data |
---|---|---|
ff79cdbf FT |
1 | import xml.dom.minidom |
2 | ||
3 | class node(object): | |
4 | def __str__(self): | |
5 | doc = xml.dom.minidom.Document() | |
6 | return self.__todom__(doc).toxml() | |
7 | ||
8 | class text(node, unicode): | |
9 | def __todom__(self, doc): | |
10 | return doc.createTextNode(self) | |
11 | ||
12 | class element(node): | |
13 | def __init__(self, ns, name, ctx): | |
14 | self.ns = ns | |
15 | self.name = unicode(name) | |
16 | self.ctx = ctx | |
17 | self.attrs = {} | |
18 | self.children = [] | |
19 | ||
20 | def __call__(self, *children, **attrs): | |
21 | for child in children: | |
22 | self.children.append(self.ctx.nodefrom(child)) | |
23 | for k, v in attrs.iteritems(): | |
24 | self.attrs[unicode(k)] = unicode(v) | |
25 | return self | |
26 | ||
27 | def __todom__(self, doc): | |
28 | el = doc.createElementNS(self.ns, self.name) | |
29 | for k, v in self.attrs.iteritems(): | |
30 | el.setAttribute(k, v) | |
31 | for child in self.children: | |
32 | el.appendChild(child.__todom__(doc)) | |
33 | return el | |
34 | ||
35 | class context(object): | |
36 | def __init__(self): | |
37 | self.nodeconv = {} | |
38 | self.nodeconv[str] = lambda ob: text(ob, "utf-8") | |
39 | self.nodeconv[unicode] = text | |
40 | self.nodeconv[int] = text | |
41 | self.nodeconv[long] = text | |
42 | self.nodeconv[float] = text | |
43 | ||
44 | def nodefrom(self, ob): | |
45 | if isinstance(ob, node): | |
46 | return ob | |
47 | if hasattr(ob, "__tonode__"): | |
48 | return ob.__tonode__() | |
49 | if type(ob) in self.nodeconv: | |
50 | return self.nodeconv[type(ob)](ob) | |
51 | raise Exception("No node conversion known for %s objects" % str(type(ob))) | |
52 | ||
53 | class constructor(object): | |
54 | def __init__(self, ns, elcls = element, ctx=None): | |
55 | self._ns = ns | |
56 | self._elcls = elcls | |
57 | if ctx is None: ctx = context() | |
58 | self._ctx = ctx | |
59 | ||
60 | def __getattr__(self, name): | |
61 | return self._elcls(self._ns, name, self._ctx) |