X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sfa%2Futil%2Frspec.py;h=515dd8647a9495a409acbaba5f3e9f0966d72b45;hb=b9a83b441a0f3d1d26cec751cf2a6af671031d57;hp=3c81b800661af414f6549e3846312354b4f89d78;hpb=4181be48285340d2c10b708701f7a4206b84f217;p=sfa.git diff --git a/sfa/util/rspec.py b/sfa/util/rspec.py index 3c81b800..515dd864 100644 --- a/sfa/util/rspec.py +++ b/sfa/util/rspec.py @@ -8,7 +8,7 @@ import httplib from xml.dom import minidom from types import StringTypes, ListType -class Rspec: +class RSpec: def __init__(self, xml = None, xsd = None, NSURL = None): ''' @@ -77,7 +77,7 @@ class Rspec: dict[key]=[value] return dict - def toDict(self, nodeDom=None, parentdict=None, siblingdict={}, parent=None): + def toGenDict(self, nodeDom=None, parentdict=None, siblingdict={}, parent=None): """ convert an XML to a nested dict: * Non-terminal nodes (elements with string children and attributes) are simple dictionaries @@ -91,26 +91,27 @@ class Rspec: if (nodeDom.hasChildNodes()): childdict={} + for attribute in nodeDom.attributes.keys(): + childdict = self.appendToDictOrCreate(childdict, attribute, nodeDom.getAttribute(attribute)) for child in nodeDom.childNodes[:-1]: if (child.nodeValue): siblingdict = self.appendToDictOrCreate(siblingdict, curNodeName, child.nodeValue) else: - childdict = self.toDict(child, None, childdict, curNodeName) + childdict = self.toGenDict(child, None, childdict, curNodeName) child = nodeDom.childNodes[-1] if (child.nodeValue): siblingdict = self.appendToDictOrCreate(siblingdict, curNodeName, child.nodeValue) + if (childdict): + siblingdict = self.appendToDictOrCreate(siblingdict, curNodeName, childdict) else: - siblingdict = self.toDict(child, siblingdict, childdict, curNodeName) - - # Keep the attributes separate from text nodes - attrdict={} - for attribute in nodeDom.attributes.keys(): - attrdict = self.appendToDictOrCreate(attrdict, attribute, nodeDom.getAttribute(attribute)) - if (attrdict): - self.appendToDictOrCreate(siblingdict, curNodeName, attrdict) + siblingdict = self.toGenDict(child, siblingdict, childdict, curNodeName) else: - self.appendToDictOrCreate(siblingdict, curNodeName, []) + childdict={} + for attribute in nodeDom.attributes.keys(): + childdict = self.appendToDictOrCreate(childdict, attribute, nodeDom.getAttribute(attribute)) + + self.appendToDictOrCreate(siblingdict, curNodeName, childdict) if (parentdict is not None): parentdict = self.appendToDictOrCreate(parentdict, parent, siblingdict) @@ -120,40 +121,40 @@ class Rspec: -# def toDict(self, nodeDom = None): -# """ -# convert this rspec to a dict and return it. -# """ -# node = {} -# if not nodeDom: -# nodeDom = self.rootNode -# -# elementName = nodeDom.nodeName -# if elementName and not elementName.startswith("#"): -# # attributes have tags and values. get {tag: value}, else {type: value} -# node[elementName] = self._attributeDict(nodeDom) -# # resolve the child nodes. -# if nodeDom.hasChildNodes(): -# for child in nodeDom.childNodes: -# childName = self._getName(child) -# # skip null children -# if not childName: -# continue -# # initialize the possible array of children -# if not node[elementName].has_key(childName): -# node[elementName][childName] = [] -# # if child node has text child nodes -# # append the children to the array as strings -# if child.hasChildNodes() and isinstance(child.childNodes[0], minidom.Text): -# for nextchild in child.childNodes: -# node[elementName][childName].append(nextchild.data) -# # convert element child node to dict -# else: -# childdict = self.toDict(child) -# for value in childdict.values(): -# node[elementName][childName].append(value) -# #node[childName].append(self.toDict(child)) -# return node + def toDict(self, nodeDom = None): + """ + convert this rspec to a dict and return it. + """ + node = {} + if not nodeDom: + nodeDom = self.rootNode + + elementName = nodeDom.nodeName + if elementName and not elementName.startswith("#"): + # attributes have tags and values. get {tag: value}, else {type: value} + node[elementName] = self._attributeDict(nodeDom) + # resolve the child nodes. + if nodeDom.hasChildNodes(): + for child in nodeDom.childNodes: + childName = self._getName(child) + # skip null children + if not childName: + continue + # initialize the possible array of children + if not node[elementName].has_key(childName): + node[elementName][childName] = [] + # if child node has text child nodes + # append the children to the array as strings + if child.hasChildNodes() and isinstance(child.childNodes[0], minidom.Text): + for nextchild in child.childNodes: + node[elementName][childName].append(nextchild.data) + # convert element child node to dict + else: + childdict = self.toDict(child) + for value in childdict.values(): + node[elementName][childName].append(value) + #node[childName].append(self.toDict(child)) + return node def toxml(self): @@ -273,7 +274,7 @@ class Rspec: """ Convert a dictionary into a dom object and store it. """ - self.rootNode = self.dict2dom(rdict, include_doc) + self.rootNode = self.dict2dom(rdict, include_doc).childNodes[0] def getDictsByTagName(self, tagname, dom = None): @@ -331,6 +332,28 @@ class Rspec: self.filter(tagname, attribute, blacklist, whitelist, child) + def merge(self, rspecs, tagname, dom=None): + """ + Merge this rspec with the requested rspec based on the specified + starting tag name. The start tag (and all of its children) will be merged + """ + tempdict = {} + if not dom: + dom = self.rootNode + + whitelist = [] + blacklist = [] + + if dom.localName in [tagname] and dom.attributes.has_key(attribute): + if whitelist and dom.attributes.get(attribute).value not in whitelist: + dom.parentNode.removeChild(dom) + if blacklist and dom.attributes.get(attribute).value in blacklist: + dom.parentNode.removeChild(dom) + + if dom.hasChildNodes(): + for child in dom.childNodes: + self.filter(tagname, attribute, blacklist, whitelist, child) + def validateDicts(self): types = { 'EInt' : int, @@ -362,7 +385,7 @@ class Rspec: -class RecordSpec(Rspec): +class RecordSpec(RSpec): root_tag = 'record' def parseDict(self, rdict, include_doc = False): @@ -375,7 +398,7 @@ class RecordSpec(Rspec): record_dict = rdict if not len(rdict.keys()) == 1: record_dict = {self.root_tag : rdict} - return Rspec.dict2dom(self, record_dict, include_doc) + return RSpec.dict2dom(self, record_dict, include_doc) # vim:ts=4:expandtab