sample configSfi.sh for demo scripts
[sfa.git] / rspec / rspecxlate.py
1 #!/usr/bin/python
2
3 # $HeadURL$
4 # $Id$
5
6 #
7 # Validate RSPEC hiearchy, values, types, and names using supplied xsd.
8 # Class to translate xml to dict
9 #
10 # Faiyaz Ahmed <faiyaza at cs dot princeton dot edu>
11 #
12 # Copyright 2009 Princeton University
13 # http://www.planet-lab.org
14 #
15
16 import sys
17 import pprint
18 import os
19 from xml.dom import minidom
20 import logging 
21 import httplib
22
23 logging.basicConfig(level=logging.DEBUG)
24
25
26 class Xmlxlate(file):
27     '''Manipulates xml into python dict'''
28     def __init__(self, file):
29         filedom = minidom.parse(file)
30         if filedom.nodeName == "#document":
31             self.xmlDom = filedom.childNodes[0]
32         else:
33             self.xmlDom = filedom
34         self.xmlDict = self.nodeDict()
35         
36        
37     #def _getSchema(self):
38     #    '''If the schema doesn't exist at the NameSpace's URL, then use the 
39     #       local file.'''
40     #    conn = httplib.HTTPConnection(self.NSURL)
41     #    conn.request("GET", "/" + self.xsd)
42     #    r1 = conn.getresponse()
43     #    if r1.status != 200:
44     #        logging.debug("http://%s/%s: file not found" %(self.NSURL,self.xsd))
45     #        if os.path.exists(self.xsd):
46     #            logging.debug("using local copy.")
47     #            self.schemaDom = minidom.parse(self.xsd)
48     #    else:
49     #        self.schemaDom = minidom.parseString(r1.read())
50     #    # XML begings with a '#document'.  Just check to be safe.
51     #    if self.schemaDom.nodeName == "#document": 
52     #        self.schemaDom = self.schemaDom.childNodes[0]
53  
54
55     def _getText(self, nodelist):
56         rc = ""
57         for node in nodelist:
58             if node.nodeType == node.TEXT_NODE:
59                 rc = rc + node.data
60         return rc
61     
62     def _getName(self, node):
63         '''Gets name of node. If tag has no name, then return tag's localName'''
64         if not node.nodeName.startswith("#"):
65             if node.attributes.has_key("name"):
66                 name = node.attributes.get("name").value
67             else: 
68                 name = node.localName
69         return name
70
71     def nodeDict(self, nodeDom = None):
72         '''Traverse complex node.  Create a dict 
73         {name : [{attributename : {name: value,}, sequence]}'''
74         children = [] # array of dicts.  1 for each element/attribute.
75         node = {}
76         # if a dom isn't passed in the arguments, use the one defined in the class.
77         if not nodeDom: nodeDom = self.xmlDom
78         if nodeDom.nodeName and not nodeDom.nodeName.startswith("#"):
79             # attributes have tags and values.  get {tag: value}, else {type: value} 
80             children.append(self._attributeDict(nodeDom))
81             # resolve the child nodes.
82             if nodeDom.hasChildNodes():
83                 for child in nodeDom.childNodes:
84                         childelems = self.nodeDict(child)
85                         if len(childelems): children.append(childelems)
86             node = { self._getName(nodeDom) : children}
87         return node
88     
89     
90     # Attribute.  {name : nameofattribute, {items: values})
91     def _attributeDict(self, attributeDom):
92         '''Traverse single attribute node.  Create a dict {attributename : {name: value,}]}'''
93         node = {} # parsed dict
94         for attr in attributeDom.attributes.keys():
95             node[attr] = attributeDom.attributes.get(attr).value
96         return node
97
98    
99 def main(fname):
100     pp = pprint.PrettyPrinter(indent=4)
101     s = Xmlxlate(fname)
102
103     print "Testing Whole Doc:"
104     pp.pprint(s.xmlDict)
105
106     print "Testing Complex Type:"
107     pp.pprint(s.nodeDict(s.xmlDom.childNodes[21]))
108
109     print "Testing rspec parsing:"
110     rspec = Xmlxlate("sample_rspec.xml") 
111     pp.pprint(rspec.xmlDict)
112
113 if __name__ == '__main__':  
114     main(fname="planetlab.xsd")