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