Fix parseDict()
[sfa.git] / sfa / util / rspec.py
index 3c81b80..903365c 100644 (file)
@@ -77,7 +77,7 @@ class Rspec:
             dict[key]=[value]
         return dict
 
-    def toDict(self, nodeDom=None, parentdict=None, siblingdict={}, parent=None):
+    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
@@ -91,26 +91,27 @@ class Rspec:
 
         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.toDict(child, None, childdict, curNodeName)
+                    childdict = self.toGenDict(child, None, childdict, curNodeName)
 
             child = nodeDom.childNodes[-1]
             if (child.nodeValue):
                 siblingdict = self.appendToDictOrCreate(siblingdict, curNodeName, child.nodeValue)
+                if (childdict):
+                    siblingdict = self.appendToDictOrCreate(siblingdict, curNodeName, childdict)
             else:
-                siblingdict = self.toDict(child, siblingdict, childdict, curNodeName)
-
-            # Keep the attributes separate from text nodes
-            attrdict={}
-            for attribute in nodeDom.attributes.keys():
-                attrdict = self.appendToDictOrCreate(attrdict, attribute, nodeDom.getAttribute(attribute))
-            if (attrdict):
-                self.appendToDictOrCreate(siblingdict, curNodeName, attrdict)
+                siblingdict = self.toGenDict(child, siblingdict, childdict, curNodeName)
         else:
-            self.appendToDictOrCreate(siblingdict, curNodeName, [])
+            childdict={}
+            for attribute in nodeDom.attributes.keys():
+                childdict = self.appendToDictOrCreate(childdict, attribute, nodeDom.getAttribute(attribute))
+
+            self.appendToDictOrCreate(siblingdict, curNodeName, childdict)
             
         if (parentdict is not None):
             parentdict = self.appendToDictOrCreate(parentdict, parent, siblingdict)
@@ -120,40 +121,40 @@ class Rspec:
 
 
 
-#    def toDict(self, nodeDom = None):
-#        """
-#        convert this rspec to a dict and return it.
-#        """
-#        node = {}
-#        if not nodeDom:
-#             nodeDom = self.rootNode
-#  
-#        elementName = nodeDom.nodeName
-#        if elementName and not elementName.startswith("#"):
-#            # attributes have tags and values.  get {tag: value}, else {type: value}
-#            node[elementName] = self._attributeDict(nodeDom)
-#            # resolve the child nodes.
-#            if nodeDom.hasChildNodes():
-#                for child in nodeDom.childNodes:
-#                    childName = self._getName(child)
-#                    # skip null children 
-#                    if not childName:
-#                        continue
-#                    # initialize the possible array of children        
-#                    if not node[elementName].has_key(childName):
-#                        node[elementName][childName] = []
-#                    # if child node has text child nodes
-#                    # append the children to the array as strings
-#                    if child.hasChildNodes() and isinstance(child.childNodes[0], minidom.Text):
-#                        for nextchild in child.childNodes:
-#                            node[elementName][childName].append(nextchild.data)
-#                    # convert element child node to dict
-#                    else:       
-#                        childdict = self.toDict(child)
-#                        for value in childdict.values():
-#                            node[elementName][childName].append(value)
-#                    #node[childName].append(self.toDict(child))
-#        return node
+    def toDict(self, nodeDom = None):
+        """
+        convert this rspec to a dict and return it.
+        """
+        node = {}
+        if not nodeDom:
+             nodeDom = self.rootNode
+  
+        elementName = nodeDom.nodeName
+        if elementName and not elementName.startswith("#"):
+            # attributes have tags and values.  get {tag: value}, else {type: value}
+            node[elementName] = self._attributeDict(nodeDom)
+            # resolve the child nodes.
+            if nodeDom.hasChildNodes():
+                for child in nodeDom.childNodes:
+                    childName = self._getName(child)
+                    # skip null children 
+                    if not childName:
+                        continue
+                    # initialize the possible array of children        
+                    if not node[elementName].has_key(childName):
+                        node[elementName][childName] = []
+                    # if child node has text child nodes
+                    # append the children to the array as strings
+                    if child.hasChildNodes() and isinstance(child.childNodes[0], minidom.Text):
+                        for nextchild in child.childNodes:
+                            node[elementName][childName].append(nextchild.data)
+                    # convert element child node to dict
+                    else:       
+                        childdict = self.toDict(child)
+                        for value in childdict.values():
+                            node[elementName][childName].append(value)
+                    #node[childName].append(self.toDict(child))
+        return node
 
   
     def toxml(self):
@@ -273,7 +274,7 @@ class Rspec:
         """
         Convert a dictionary into a dom object and store it.
         """
-        self.rootNode = self.dict2dom(rdict, include_doc)
+        self.rootNode = self.dict2dom(rdict, include_doc).childNodes[0]
  
  
     def getDictsByTagName(self, tagname, dom = None):