(no commit message)
[sfa.git] / sfa / util / rspec.py
index a184dc0..902733c 100644 (file)
@@ -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):
         '''
@@ -70,6 +70,52 @@ class Rspec():
         return node
   
  
+    def appendToDictOrCreate(self, dict, key, value):
+        if (dict.has_key(key)):
+            dict[key].append(value)
+        else:
+            dict[key]=[value]
+        return dict
+
+    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
+          * Terminal nodes (the rest) are nested dictionaries
+        """
+
+        if (not nodeDom):
+            nodeDom=self.rootNode
+
+        curNodeName = nodeDom.localName
+
+        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.toGenDict(child, None, childdict, curNodeName)
+
+            child = nodeDom.childNodes[-1]
+            if (child.nodeValue):
+                siblingdict = self.appendToDictOrCreate(siblingdict, curNodeName, child.nodeValue)
+            else:
+                siblingdict = self.toGenDict(child, siblingdict, childdict, curNodeName)
+        else:
+            siblingdict[curNodeName]=[]
+            
+        if (parentdict is not None):
+            parentdict = self.appendToDictOrCreate(parentdict, parent, siblingdict)
+            return parentdict
+        else:
+            return siblingdict
+
+
+
     def toDict(self, nodeDom = None):
         """
         convert this rspec to a dict and return it.