Formatting.
[sfa.git] / util / rspec.py
1 import sys
2 import pprint
3 import os
4 from xml.dom import minidom
5 from types import StringTypes
6
7 class Rspec():
8
9     def __init__(self, xml = None, xsd = None):
10         self.xsd = xsd
11         self.rootNode = None
12         if xml:
13             self.parse_string(xml)
14       
15   
16     def _getText(self, nodelist):
17         rc = ""
18         for node in nodelist:
19             if node.nodeType == node.TEXT_NODE:
20                 rc = rc + node.data
21         return rc
22   
23     # The rspec is comprised of 2 parts, and 1 reference:
24     # attributes/elements describe individual resources
25     # complexTypes are used to describe a set of attributes/elements
26     # complexTypes can include a reference to other complexTypes.
27   
28   
29     def _getName(self, node):
30         '''Gets name of node. If tag has no name, then return tag's localName'''
31         name = None
32         if not node.nodeName.startswith("#"):
33             if node.localName:
34                 name = node.localName
35             elif node.attributes.has_key("name"):
36                 name = node.attributes.get("name").value
37         return name     
38   
39   # Attribute.  {name : nameofattribute, {items: values})
40   def _attributeDict(self, attributeDom):
41         '''Traverse single attribute node.  Create a dict {attributename : {name: value,}]}'''
42         node = {} # parsed dict
43         for attr in attributeDom.attributes.keys():
44             node[attr] = attributeDom.attributes.get(attr).value
45         return node
46   
47  
48     def toDict(self, nodeDom = None):
49          """
50          convert this rspec to a dict and return it.
51         """
52         node = {}
53         if not nodeDom:
54              nodeDom = self.rootNode
55   
56         elementName = nodeDom.nodeName
57         if elementName and not elementName.startswith("#"):
58             # attributes have tags and values.  get {tag: value}, else {type: value}
59             node[elementName] = self._attributeDict(nodeDom)
60             #node.update(self._attributeDict(nodeDom))
61             # resolve the child nodes.
62             if nodeDom.hasChildNodes():
63                 for child in nodeDom.childNodes:
64                     childName = self._getName(child)
65                     if not childName:
66                         continue
67                     if not node[elementName].has_key(childName):
68                         node[elementName][childName] = []       
69                         #node[childName] = []
70                     childdict = self.toDict(child)
71                     for value in childdict.values():
72                         node[elementName][childName].append(value)
73                     #node[childName].append(self.toDict(child))
74         return node
75   
76     def toxml(self):
77         """
78         convert this rspec to an xml string and return it.
79         """
80         return self.rootNode.toxml()
81   
82     def toprettyxml(self):
83         """
84         print this rspec in xml in a pretty format.
85         """
86         return self.rootNode.toprettyxml()
87   
88     def parseFile(self, filename):
89         """
90         read a local xml file and store it as a dom object.
91         """
92         dom = minidom.parse(filename)
93         self.rootNode = dom.childNodes[0]
94   
95   
96     def parseString(self, xml):
97         """
98         read an xml string and store it as a dom object.
99         """
100         xml = xml.replace('\n', '').replace('\t', '').strip()
101         dom = minidom.parseString(xml)
102         self.rootNode = dom.childNodes[0]
103  
104     def dict2dom(self, rdict, include_doc = False):
105         """
106         convert a dict object into a dom object.
107         """
108      
109     def elementNode(tagname, rd):
110         element = minidom.Element(tagname)   
111         for key in rd.keys():
112             if isinstance(rd[key], StringTypes):
113                 element.setAttribute(key, rd[key])
114             elif isinstance(rd[key], dict):
115                  child = elementNode(key, rd[key])
116                  element.appendChild(child)
117             elif isinstance(rd[key], list):
118                  for item in rd[key]:
119                      child = elementNode(key, item)
120                      element.appendChild(child)
121           return element
122                      
123         node = elementNode(rdict.keys()[0], rdict.values()[0])
124         if include_doc:
125             rootNode = minidom.Document()
126             rootNode.appendChild(node)
127         else:
128             rootNode = node
129         return rootNode
130  
131 def parseDict(self, rdict, include_doc = True):
132       """
133       Convert a dictionary into a dom object and store it.
134       """
135       self.rootNode = self.dict2dom(rdict, include_doc)
136  
137  
138 def getDictsByTagName(self, tagname, dom = None):
139       """
140       Search the dom for all elements with the specified tagname
141       and return them as a list of dicts
142       """
143       if not dom:
144           dom = self.rootNode
145       dicts = []
146       doms = dom.getElementsByTagName(tagname)
147       dictlist = [self.toDict(d) for d in doms]
148       for item in dictlist:
149           for value in item.values():
150               dicts.append(value)
151       return dicts
152
153 #  vim:ts=4:expandtab