Project

General

Profile

1 11 aaronmk
# XML DOM tree manipulation
2
3
from xml.dom import Node
4
5
class MappingException(Exception): pass
6
7
def by_tag_name(parent, name):
8
    node = parent.lastChild
9
    while node != None and\
10
    not (node.nodeType == Node.ELEMENT_NODE and node.tagName == name):
11
        node = node.previousSibling
12
    return node
13
14
def value(node):
15
    if node.firstChild != None: return node.firstChild.nodeValue
16
    else: return node.nodeValue
17
18
def by_path(doc, path, create=False, parent=None):
19
    if not parent: parent = doc.documentElement
20
    for elem in path:
21
        node = None
22
        if elem.is_attr: node = parent.getAttributeNode(elem.name)
23
        elif elem.name == '.': node = parent
24
        else: node = by_tag_name(parent, elem.name)
25
        if node != None and elem.value != None and value(node) != elem.value:
26
            node = None
27
        for attr in elem.attrs:
28
            if by_path(doc, attr, parent=node) == None: node = None; break
29
        if node == None:
30
            if not create: return None
31
            if elem.is_attr:
32
                parent.setAttribute(elem.name, '')
33
                node = parent.getAttributeNode(elem.name)
34
            else: node = parent.appendChild(doc.createElement(elem.name))
35
            if elem.value != None:
36
                if node.nodeType == Node.ELEMENT_NODE:
37
                    node.appendChild(doc.createTextNode(elem.value))
38
                else: node.nodeValue = elem.value
39
            for attr in elem.attrs: by_path(doc, attr, create, node)
40
        parent = node
41
    return parent