From: Faiyaz Ahmed Date: Tue, 20 Jan 2009 21:56:38 +0000 (+0000) Subject: Parses xsd into dict. Probably can be optimized. X-Git-Tag: sfa-0.9-0@14641~743 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=a4ae270b9d5fd0063ccf6f12488f4d504d983a8b;p=sfa.git Parses xsd into dict. Probably can be optimized. --- diff --git a/rspec/rspecvalidate.py b/rspec/rspecvalidate.py index 17f208f0..e09a21b4 100644 --- a/rspec/rspecvalidate.py +++ b/rspec/rspecvalidate.py @@ -15,7 +15,14 @@ import sys import pprint from xml.dom import minidom +from logging import Logger +logger = Logger + +# The rspec is comprised of 2 parts, and 1 reference: +# attributes/elements describe individual resources +# complexTypes are used to describe a set of attributes/elements +# complexTypes can include a reference to other complexTypes. def getText(nodelist): rc = "" @@ -24,42 +31,69 @@ def getText(nodelist): rc = rc + node.data return rc -# complexType: a supernode comprised of element nodes below it. -def traverseComplexType(cmpTypeNode): - _elements = {} - if cmpTypeNode.hasChildNodes(): - for n in cmpTypeNode.getElementsByTagName("xsd:attribute"): - _elements[n.getAttribute("name")] = {'type': n.getAttribute("type")} +def getName(node): + '''Gets name of node. Raises NameError exception if no name''' + if node.attributes.has_key("name"): + name = node.attributes.get("name").value + else: raise Exception("Can't find 'name'") + return name +# complexType: a supernode comprised of attribute and/or element nodes below it. +def complexTypeDict(cmpTypeDom): + '''Traverse complex node. Create a dict {name : [{attributename : {name: value,}, sequence]}''' + children = [] # array of dicts. 1 for each element/attribute. + if cmpTypeDom.hasChildNodes(): + for child in cmpTypeDom.childNodes: + # attributes have tags and values. get {tag: value} + if child.localName in ("attribute", "element"): children.append(attributeDict(child)) + # sequence is a list of elements. append dict to list + elif child.localName == "sequence": children.append(sequenceList(child)) + elif child.localName == "simpleType": pass #unsure what this type is used for. + else: Exception("Unknown type: %s" % child.localName) + node = { getName(cmpTypeDom) : children} + return node -# Element. {name, value, default} -def Element(elementDom): - node = {} #parsed dict - for attr in elementDom.attributes.keys(): - node[attr] = elementDom.attributes.get(attr).value - # set the name to the name of the element. otherwise, node name. - if elementDom.attributes.has_key("name"): - element = {(elementDom.localName, elementDom.attributes.get("name").value) : node} - else: - element = {elementDom.localName: node} - # print repr(element) - # print - return element +# Attribute. {name : nameofattribute, {items: values}) +def attributeDict(attributeDom): + '''Traverse single attribute node. Create a dict {attributename : {name: value,}]}''' + node = {} # parsed dict + for attr in attributeDom.attributes.keys(): + node[attr] = attributeDom.attributes.get(attr).value + attribute = {getName(attributeDom) : node} + return attribute -# Sequence is a list of dicts. Each dict is an element type with Type fields -def Sequence(sequenceNode): - pass +def sequenceList(sequenceDom): + '''Return list of elements/attributes in sequence list''' + sequence = [] + if sequenceDom.localName == "sequence": + # for sanity + if sequenceDom.hasChildNodes: + for seqitm in sequenceDom.childNodes: + if seqitm.localName in ("element", "attribute"): + sequence.append(attributeDict(seqitm)) + else: print "Idunno what %s is" % seqitm.localName + else: raise NameError + return sequence -def buildDict(document, docdict = {}): +def schemaDict(document): + schema = {} + '''Parse the given schema and produce a dict of types''' if document.hasChildNodes(): - for i in document.childNodes: - if i.attributes: docdict.update({ i.localName: buildDict(i, docdict)}) - if document.attributes: docdict.update(Element(document)) - return docdict + for i in document.childNodes: + if i.localName in ('element', 'attribute'): + schema.update(attributeDict(i)) + elif i.localName == "complexType": + schema.update(complexTypeDict(i)) + else: print "Idunno what %s is" % i.localName + return schema def main(fname): pp = pprint.PrettyPrinter(indent=4) - pp.pprint(buildDict(minidom.parse(fname))) + dom = minidom.parse(fname) + print "Testing Complex Type:" + pp.pprint(complexTypeDict(dom.childNodes[0].childNodes[15])) + print "Testing Whole doc:" + pp.pprint(schemaDict(dom.childNodes[0])) if __name__ == '__main__': main(fname="planetlab.xsd")