[XML-SIG] femto-dom?
Rich Salz
rsalz@zolera.com
Fri, 22 Jun 2001 21:11:54 -0400
This is a multi-part message in MIME format.
--------------8BE50EE5E03BF832881B3001
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
We needed a way to create XML fragments that we could then output within
other documents. The DOM API is way too heavyweight. So we took the
Canonicalize() routine, looked at the attributes it uses, and created
this femto-DOM.
Is there any interest in this? If so I'll document it (where?) and
check it in.
/r$
--------------8BE50EE5E03BF832881B3001
Content-Type: text/plain; charset=us-ascii;
name="simplenode.py"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="simplenode.py"
#! /usr/bin/env python
'''Simple DOM node builder.
'''
from xml.dom import Node
from xml.ns import XMLNS
def _splitname(name):
'''Split a name, returning prefix, localname, qualifiedname.
'''
i = name.find(':')
if i == -1: return '', name, name
return name[:i], name[i + 1:], name
def _initattrs(n, type):
'''Set the initial node attributes.
'''
n.attributes = []
n.childNodes = []
n.nodeType = type
n.parentNode = None
n.namespaceURI = ''
class SimpleContentNode:
'''A CDATA, TEXT, or COMMENT node.
'''
def __init__(self, type, text):
_initattrs(self, type)
self.data = text
class SimplePINode:
'''A PI node.
'''
def __init__(self, name, value):
_initattrs(self, Node.PROCESSING_INSTRUCTION_NODE)
self.name, self.value, self.nodeValue = name, value, value
class SimpleAttributeNode:
'''An element attribute node.
'''
def __init__(self, name, value):
_initattrs(self, Node.ATTRIBUTE_NODE)
self.value, self.nodeValue = value, value
self.prefix, self.localName, self.nodeName = _splitname(name)
class SimpleElementNode:
'''An element. Might have children, text, and attributes.
'''
def __init__(self, name, nsdict = None, newline = 1):
if nsdict:
self.nsdict = nsdict.copy()
else:
self.nsdict = {}
_initattrs(self, Node.ELEMENT_NODE)
self.prefix, self.localName, self.nodeName = _splitname(name)
self.namespaceURI = self.nsdict.get(self.prefix, None)
for k,v in self.nsdict.items():
self.AddNSAttr(k, v)
if newline: self.AddText('\n')
def nslookup(self, key):
n = self
while n:
if n.nsdict.has_key(key): return n.nsdict[key]
n = n.parentNode
raise KeyError, "namespace prefix %s not found" % key
def AddAttr(self, name, value):
n = SimpleAttributeNode(name, value)
n.parentNode = self
if not n.prefix:
n.namespaceURI = None
else:
n.namespaceURI = self.nslookup(n.prefix)
self.attributes.append(n)
return self
def AddNSAttr(self, prefix, value):
if prefix:
n = SimpleAttributeNode("xmlns:" + prefix, value)
else:
n = SimpleAttributeNode("xmlns", value)
n.parentNode, n.namespaceURI = self, XMLNS.BASE
self.attributes.append(n)
self.nsdict[prefix] = value
return self
def AddDefaultNSAttr(self, value):
return self.AddNSAttr('', value)
def AddChild(self, n):
n.parentNode = self
if n.namespaceURI == None: n.namespaceURI = self.namespaceURI
self.childNodes.append(n)
return self
def AddText(self, text):
n = SimpleContentNode(Node.TEXT_NODE, text)
return self.AddChild(n)
def AddCDATA(self, text):
n = SimpleContentNode(Node.CDATA_SECTION_NODE, text)
return self.AddChild(n)
def AddComment(self, text):
n = SimpleContentNode(Node.COMMENT_NODE, text)
return self.AddChild(n)
def AddPI(self, name, value):
n = SimplePINode(name, value)
return self.AddChild(n)
return self
def AddElement(self, name, nsdict = None, newline = 1):
n = SimpleElementNode(name, nsdict, newline)
self.AddChild(n)
return n
if __name__ == '__main__':
e = SimpleElementNode('z', {'': 'uri:example.com', 'q':'q-namespace'})
n = e.AddElement('zchild')
n.AddNSAttr('d', 'd-uri')
n.AddAttr('foo', 'foo-value')
n.AddText('some text for d\n')
n.AddElement('d:k2').AddText('innermost txt\n')
e.AddElement('q:e-child-2').AddComment('This is a comment')
e.AddText('\n')
e.AddElement('ll:foo', { 'll': 'example.org'})
e.AddAttr('eattr', '''eat at joe's''')
from xml.dom.ext import Canonicalize
print Canonicalize(e, comments=1)
--------------8BE50EE5E03BF832881B3001--