* get encoding to work a bit, not there yet... so many changes to list :(

This commit is contained in:
Eray Özkural
2005-09-23 17:44:21 +00:00
parent ff76e166bd
commit fb48f82574
3 changed files with 74 additions and 56 deletions
+6 -1
View File
@@ -31,7 +31,8 @@ def getNodeAttribute(node, attrname):
return node.getAttribute(attrname)
def getTagByName(parent, childName):
return [x for x in parent.childNodes if x.nodeType == x.ELEMENT_NODE if x.tagName == childName]
return [x for x in parent.childNodes
if x.nodeType == x.ELEMENT_NODE if x.tagName == childName]
def getNodeText(node, tagpath = ""):
"""get the first child and expect it to be text!"""
@@ -131,6 +132,10 @@ def addNode(dom, node, tagpath, newnode = None):
tags = []
if tagpath != "":
tags = tagpath.split('/') # tag chain
else:
addTagPath(dom, node, [], newnode)
return node
assert len(tags)>0 # we want a chain
# iterative code to search for the path
+65 -54
View File
@@ -163,6 +163,7 @@ class autoxml(type):
"""
def __init__(cls, name, bases, dict):
"""entry point for metaclass code"""
print 'generating class', name
# add XmlFile as one of the superclasses, we're smart
@@ -202,6 +203,7 @@ class autoxml(type):
# generate top-level helper functions
cls.initializers = inits
def initialize(self):
# XmlFile.__init__(self, cls.tag)
for init in self.__class__.initializers:
init(self)
cls.__init__ = initialize
@@ -217,6 +219,7 @@ class autoxml(type):
node = xml.newNode(cls.tag)
for encode_member in self.__class__.encoders:
encode_member(self, xml, node)
xml.dom.documentElement = node
return node
cls.encode = encode
@@ -238,33 +241,42 @@ class autoxml(type):
assert type(tag_type) == type(type)
def readtext(node, attr):
return getNodeAttribute(node, attr)
def createnode(xml, attr):
return xml.newAttribute(attr)
def writetext(node, attr, text):
def createnode(xml, attr_name):
return xml.newAttribute(attr_name) # create an attribute node
def writetext(xml, attr, nil, text):
attr.value = text
node.setAttributeNode(attr)
anonfuns = cls.gen_anon_basic(attr, spec, readtext, createnode, writetext)
def mergetext(node, attr):
pass
node.setAttributeNode(node, attr)
return cls.gen_named_comp(attr, spec, anonfuns, mergetext)
def gen_tag_member(cls, tag):
"""generate helper funs for tag member of class"""
spec = getattr(cls, 't_' + tag)
def readtext(node, tagpath):
return getNodeText(getNode(node, tagpath))
def createnode(xml, tag):
return xml.newNode(tag)
def writetext(node, text):
node.addText(node, text)
anonfuns = cls.gen_tag(tag, spec, createnode, readtext, writetext)
def mergetext(xml, node, tagpath):
pass
head, tail = cls.tagpath_head_last(tagpath)
subnode = xml.newNode(tail)
anonfuns = cls.gen_tag(tag, spec)
def mergetext(node, newnode):
print 'mergenode', node, newnode
node.appendChild(newnode)
return cls.gen_named_comp(tag, spec, anonfuns, mergetext)
def gen_named_comp(cls, token, spec, anonfuns, createnode):
def gen_tag(cls, tag, spec):
"""generate readers and writers for the tag"""
tag_type = spec[0]
if type(tag_type) is types.TypeType:
def readtext(node, tagpath):
return getNodeText(node, tagpath)
def createnode(xml, tag):
return xml.newNode(tag)
def writetext(xml, node, tagpath, text):
xml.addTextNodeUnder(node, tagpath, text)
return cls.gen_anon_basic(tag, spec, readtext,
createnode, writetext)
elif type(tag_type) is types.ListType:
return cls.gen_list_tag(tag, spec)
elif type(tag_type) is autoxml or type(tag_type) is types.ClassType:
return cls.gen_class_tag(tag, spec)
def gen_named_comp(cls, token, spec, anonfuns, mergetext):
"""generate a named component tag/attr. a decoration of
anonymous functions that do not bind to variable names"""
name = cls.mixed_case(token)
@@ -286,7 +298,9 @@ class autoxml(type):
value = getattr(self, name)
else:
value = None
return encode_a(xml, self.dom.documentElement, value)
newnode = encode_a(xml, value)
if newnode:
mergetext(node, newnode)
def format(self):
if hasattr(self, name):
@@ -299,28 +313,20 @@ class autoxml(type):
return (init, decode, encode, format)
def gen_tag(cls, tag, spec, readtext, createnode, writetext):
"""generate readers and writers for the tag"""
tag_type = spec[0]
if type(tag_type) is types.TypeType:
return cls.gen_anon_basic(tag, spec, readtext, createnode, writetext)
elif type(tag_type) is types.ListType:
return cls.gen_list_tag(tag, spec)
elif type(tag_type) is autoxml or type(tag_type) is types.ClassType:
return cls.gen_class_tag(tag, spec)
def mixed_case(cls, identifier):
"""helper function to turn token name into mixed case"""
identifier_p = identifier[0].lower() + identifier[1:]
return identifier_p
if identifier is "":
return ""
else:
return identifier[0].lower() + identifier[1:]
def tagpath_head_last(cls, tag_path):
def tagpath_head_last(cls, tagpath):
"returns split of the tag path into last tag and the rest"
try:
lastsep = tagpath.rindex('/')
except ValueError, e:
return ('', tag_path)
return (tag_path[:laststep], tag_path[laststep+1:])
return ('', tagpath)
return (tagpath[:lastsep], tagpath[lastsep+1:])
def parse_spec(cls, token, spec):
"""decompose member specification"""
@@ -364,12 +370,12 @@ class autoxml(type):
else:
return None
def encode(xml, node, value):
def encode(xml, value):
"""encode given value inside DOM node"""
if value:
path = cls.tagpath_head_last(tagpath)
node = createnode(xml, token)
writetext(node, str(value))
head, last = cls.tagpath_head_last(tagpath)
node = createnode(xml, last)
writetext(xml, node, head, str(value))
return node
else:
if req == mandatory:
@@ -424,17 +430,19 @@ class autoxml(type):
def gen_list_tag(cls, tag, spec):
"""generate a list datatype"""
name, tag_type, req, path = cls.parse_spec(tag, spec)
head, last = cls.tagpath_head_last(path)
if len(tag_type) != 1:
raise Error('List type must contain only one element')
def readtext(node, tagpath):
return getNodeText(getNode(node, tagpath))
def createnode(xml, tag):
return xml.newNode(tag)
def writetext(node, text):
node.addText(node, text)
x = cls.gen_tag(tag, [tag_type[0], mandatory],
readtext, createnode, writetext)
# def readtext(node, tagpath):
# print 'shit', node, tagpath
# return getNodeText(node)
# def createnode(xml, tag):
# return xml.newNode(last)
# def writetext(node, text):
# node.addText(node, text)
x = cls.gen_tag(last, [tag_type[0], mandatory])
(init_item, decode_item, encode_item, format_item) = x
def init():
@@ -447,16 +455,18 @@ class autoxml(type):
if len(nodes) is 0 and req is mandatory:
raise Error('Mandatory list empty')
for node in nodes:
l.append(decode_item(node))
dummy = node.ownerDocument.createElement(last)
dummy.appendChild(node)
l.append(decode_item(dummy))
return l
def encode(xml, node, l):
if len(l) > 0:
def encode(xml, l):
dummy = xml.newNode("Dummy")
if len(l) > 0:
for item in l:
item_node = xml.newNode(path)
encode_item(xml, item, item_node)
xml.addTextNodeUnder(item_node)
return node
item_node = encode_item(xml, item)
xml.addNodeUnder(dummy, last, item_node)
return getNode(dummy, "Dummy")
else:
if req is mandatory:
raise Error('Mandatory list empty')
@@ -519,11 +529,11 @@ class XmlFile(object):
return self.dom.createTextNode(text)
def newAttribute(self, attr):
return self.dom.createAttribute(name)
return self.dom.createAttribute(attr)
# read helpers
def getNode(self, tagPath):
def getNode(self, tagPath = ""):
"""returns the *first* matching node for given tag path."""
self.verifyRootTag()
return getNode(self.dom.documentElement, tagPath)
@@ -590,4 +600,5 @@ class XmlFile(object):
def addTextNodeUnder(self, node, tagPath, text):
"add a text node under given node with tag path (phew)"
print "addtextnodeunder", node, tagPath, text
return self.addNodeUnder(node, tagPath, self.newTextNode(text))
+3 -1
View File
@@ -56,8 +56,10 @@ class XmlFileTestCase(unittest.TestCase):
print '*', string
#self.assert_(string.startswith('Name'))
xml = xmlfile.XmlFile('A')
a.encode(xml)
a.otherInfo.encode(xml)
xml.writexml('/tmp/a.xml')
print 'A DONE'
return
xml = xmlfile.XmlFile('A')
a2 = A()
a2.name = "Baris Metin"