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