]> git.sesse.net Git - xml-template/blob - python/xmltemplate.py
Start implementing cloning in Python.
[xml-template] / python / xmltemplate.py
1 #! /usr/bin/python
2 import re
3 import xml.dom.minidom
4
5 def process_file(filename, obj, clean = True):
6         doc = xml.dom.minidom.parse(filename)
7         process(doc, obj, clean)
8         return doc
9
10 def process(node, obj, clean = True):
11         if isinstance(obj, str):                        # overwrite
12                 for child in node.childNodes:
13                         node.removeChild(child)
14                 doc = _get_document_element(node)
15                 node.appendChild(doc.createTextNode(obj))
16         elif isinstance(obj, xml.dom.Node):             # overwrite
17                 pass
18         elif isinstance(obj, dict):                     # substitute
19                 for child in node.childNodes:
20                         processed = False
21
22                         if child.nodeType == xml.dom.Node.ELEMENT_NODE:
23                                 id = None
24
25                                 attrs = child.attributes
26                                 if not attrs is None:
27                                         for i in range(attrs.length):
28                                                 attr = attrs.item(0)
29                                                 if attr.namespaceURI == "http://template.sesse.net/" or attr.name == "id":
30                                                         id = attr.value
31                                                         if clean:
32                                                                 child.removeAttribute(attr.name)
33
34                                 # check all substitutions to see if we found anything
35                                 # appropriate
36                                 for key in obj.keys():
37                                         if key.startswith(child.tagName + "/"):
38                                                 child.setAttribute(key.split("/")[1], obj[key])
39                                         elif (not id is None) and key.startswith("#" + id + "/"):
40                                                 child.setAttribute(key.split("/")[1], obj[key])
41
42                                         if not processed:
43                                                 if key == child.tagName or ((not id is None) and key == "#" + id):
44                                                         process(child, obj[key], clean)
45                                                         processed = True
46
47                         if not processed:
48                                 process(child, obj, clean)
49         elif isinstance(obj, list):                     # repeat
50                 doc = _get_document_element(node)
51                 frag = doc.createElement("temporary-fragment")     # ugh
52
53                 for child in node.childNodes:
54                         frag.appendChild(child)
55                         node.removeChild(child)
56
57                 for instance in obj:
58                         newnode = frag.clone(True)
59                         node.appendChild(newnode)
60                         process(newnode, instance, clean)
61                         if clean:
62                                 _clean(newnode)
63
64                 # remove all the <fragment> tags
65
66                 for child in node.childNodes:
67                         if child.name == 'temporary-fragment':
68                                 for child2 in child.childNodes:
69                                         node.appendChild(child2)
70                                 node.removeChild(child)
71
72         if clean:
73                 _clean(node)
74
75 def alternate(tag, array, *elems):
76         return array
77
78 def _clean(node):
79         pass
80
81 # ugh
82 def _get_document_element(node):
83         if node.parentNode is None:
84                 return node
85         else:
86                 return _get_document_element(node.parentNode)