7 # Validate RSPEC hiearchy, values, types, and names using supplied xsd.
9 # Faiyaz Ahmed <faiyaza at cs dot princeton dot edu>
11 # Copyright 2009 Princeton University
12 # http://www.planet-lab.org
17 from xml.dom import minidom
18 from logging import Logger
23 NSURL = "www.planet-lab.org"
26 def getText(nodelist):
29 if node.nodeType == node.TEXT_NODE:
33 # The rspec is comprised of 2 parts, and 1 reference:
34 # attributes/elements describe individual resources
35 # complexTypes are used to describe a set of attributes/elements
36 # complexTypes can include a reference to other complexTypes.
45 h1 = httplib.HTTPConnection(NSURL)
46 h1.request("GET", "/" + xsd)
48 self.schemadom = minidom.parseString(r1)
50 def getName(self, node):
51 '''Gets name of node. Raises NameError exception if no name'''
52 if node.attributes.has_key("name"):
53 name = node.attributes.get("name").value
54 else: raise Exception("Can't find 'name'")
57 # complexType: a supernode comprised of attribute and/or element nodes below it.
58 def complexTypeDict(self, cmpTypeDom):
59 '''Traverse complex node. Create a dict
60 {name : [{attributename : {name: value,}, sequence]}'''
61 children = [] # array of dicts. 1 for each element/attribute.
62 if cmpTypeDom.hasChildNodes():
63 for child in cmpTypeDom.childNodes:
64 # attributes have tags and values. get {tag: value}
65 if child.localName in ("attribute", "element"):
66 children.append(self.attributeDict(child))
67 # sequence is a list of elements. append dict to list
68 elif child.localName == "sequence": children.append(self.sequenceList(child))
69 elif child.localName == "simpleType": pass #unsure what this type is used for.
70 elif child.localName == "complexContent":
71 else: Exception("Unknown type: %s" % child.localName)
72 node = { self.getName(cmpTypeDom) : children}
75 def complexContent(self, ccontentDom):
76 '''Traverse complexContent. Return {extention, element}'''
77 if ccontentDom.localName == "complexContent":
78 for child in ccontentDom.childNodes: pass
79 else: raise Exception("%s is not complexContent" % contentDom.localName)
82 # Attribute. {name : nameofattribute, {items: values})
83 def attributeDict(self, attributeDom):
84 '''Traverse single attribute node. Create a dict {attributename : {name: value,}]}'''
85 node = {} # parsed dict
86 for attr in attributeDom.attributes.keys():
87 node[attr] = attributeDom.attributes.get(attr).value
88 attribute = {self.getName(attributeDom) : node}
91 # Sequence. [{tag:value},]
92 def sequenceList(self, sequenceDom):
93 '''Return list of elements/attributes in sequence list'''
95 if sequenceDom.localName == "sequence":
97 if sequenceDom.hasChildNodes:
98 for seqitm in sequenceDom.childNodes:
99 if seqitm.localName in ("element", "attribute"):
100 sequence.append(self.attributeDict(seqitm))
101 else: print "Idunno what %s is" % seqitm.localName
102 else: raise NameError
105 def schemaDict(self, document):
107 '''Parse the given schema and produce a dict of types'''
108 if document.hasChildNodes():
109 for i in document.childNodes:
110 if i.localName in ('element', 'attribute'):
111 self.schema.update(self.attributeDict(i))
112 elif i.localName == "complexType":
113 self.schema.update(self.complexTypeDict(i))
114 else: print "Idunno what %s is" % i.localName
121 pp = pprint.PrettyPrinter(indent=4)
122 dom = minidom.parse(fname)
123 print "Testing Complex Type:"
125 pp.pprint(s.complexTypeDict(dom.childNodes[0].childNodes[21]))
126 print "Testing Whole doc:"
127 pp.pprint(s.schemaDict(dom.childNodes[0]))
129 if __name__ == '__main__':
130 main(fname="planetlab.xsd")