Switch to side-by-side view

--- a/OSSEval/methodology/models.py
+++ b/OSSEval/methodology/models.py
@@ -1,7 +1,8 @@
 from django.db import models
 from entity.models import Entity
 from OSSEval.utils import xmlMinidom
-    
+from xml.dom.minidom import Node
+
 class Methodology(models.Model):
     name = models.CharField(max_length=200)
     description = models.CharField(max_length=2000,null=True,blank=True)
@@ -15,12 +16,11 @@
     
     def from_xml(self, xmldoc, insert = True):
         if not insert:
-            self.id = xmldoc.getElementsByTagName('Id')[0].firstChild.data
-        self.name = xmlMinidom.getString(xmldoc, 'Name')
-        print str(self.id) + " " + self.name
+            self.id = xmlMinidom.getNaturalAttribute(xmldoc, 'Id')
+        self.name = xmlMinidom.getStringAttribute(xmldoc, 'Name')
         self.description = xmlMinidom.getString(xmldoc, 'Description')
         self.documentation = xmlMinidom.getString(xmldoc, 'Documentation')
-        self.active = xmlMinidom.getString(xmldoc, 'Active')
+        self.active = xmlMinidom.getStringAttribute(xmldoc, 'Active')
         e = Entity()
         xml_entity = xmldoc.getElementsByTagName('Entity')[0]
         e.from_xml(xml_entity, insert)
@@ -29,14 +29,10 @@
         self.save()
         
     def to_xml(self):
-        str_xml = "<Id>" + str(self.id) + "</Id>"
-        str_xml += "<Name>" + self.name + "</Name>"
-        str_xml += "<Description>" + self.description + "</Description>"
-        str_xml += "<Documentation>" + self.documentation + "</Documentation>"
-        str_xml += "<Active>" + str(self.active) + "</Active>"
+        str_xml = "<Description><![CDATA[" + self.description + "]]></Description>"
+        str_xml += "<Documentation><![CDATA[" + self.documentation + "]]></Documentation>"
         str_xml += self.entity.to_xml()
-        return "<Methodology>" + str_xml + "</Methodology>"
-        
+        return '<Methodology Id="' + str(self.id) + '" Name="' + self.name + '" Active="' + str(self.active) + '">' + str_xml + "</Methodology>"
 
 class MethodologyVersion(models.Model):
     number = models.IntegerField()
@@ -49,10 +45,10 @@
 
     def from_xml(self, xmldoc, insert = True):
         if not insert:
-            self.id = xmldoc.getElementsByTagName('Id')[0].firstChild.data
-        self.number = xmldoc.getElementsByTagName('Number')[0].firstChild.data
-        self.created = xmlMinidom.getString(xmldoc, 'Created')
-        self.current = xmlMinidom.getString(xmldoc, 'Current')
+            self.id = xmlMinidom.getNaturalAttribute(xmldoc, 'Id')
+        self.number = xmldoc.attributes["Number"].firstChild.data
+        self.created = xmlMinidom.getStringAttribute(xmldoc, 'Created')
+        self.current = xmlMinidom.getStringAttribute(xmldoc, 'Current')
         m = Methodology()
         xml_methodology = xmldoc.getElementsByTagName('Methodology')[0]
         m.from_xml(xml_methodology, insert)
@@ -61,11 +57,12 @@
         self.save()
         # Pages
         for xml_child in xmldoc.childNodes:
-            if xml_child.tagName == 'Pages':
+            # Some nodes are text nodes (e.g. u'\n     ') I need to look just at ELEMENT_NODE
+            if xml_child.nodeType == Node.ELEMENT_NODE and xml_child.tagName == 'Pages':
                 xml_pages = xml_child
                 break
         for xml_page in xml_pages.childNodes:
-            if xml_page.tagName == 'Page':
+            if xml_page.nodeType == Node.ELEMENT_NODE and xml_page.tagName == 'Page':
                 p = Page()
                 p.from_xml(xml_page, self, None, insert)
         #WeightScenarios
@@ -75,11 +72,7 @@
             ws.from_xml(xml_weight_scenario, self, insert)
         
     def to_xml(self):
-        str_xml = "<Id>" + str(self.id) + "</Id>"
-        str_xml += "<Number>" + str(self.number) + "</Number>"
-        str_xml += "<Created>" + str(self.created) + "</Created>"
-        str_xml += "<Current>" + str(self.current) + "</Current>"
-        str_xml += self.methodology.to_xml()
+        str_xml = self.methodology.to_xml()
         str_xml += "<Pages>"
         for page in self.page_set.all():
             str_xml += page.to_xml()
@@ -89,7 +82,7 @@
             str_xml += weight_scenario.to_xml()
         str_xml += "</WeightScenarios>"
              
-        return "<MethodologyVersion>" + str_xml + "</MethodologyVersion>"
+        return '<MethodologyVersion Id="' + str(self.id) + '" Number="' + str(self.number) + '" Created="' + str(self.created) + '" Current="' + str(self.current) + '">' + str_xml + "</MethodologyVersion>"
 
 class Page(models.Model):
     name = models.CharField(max_length=200)
@@ -102,33 +95,38 @@
     
     def from_xml(self, xmldoc, methodology_version, parent_page, insert = True):
         if not insert:
-            self.id = xmldoc.getElementsByTagName('Id')[0].firstChild.data
-        self.name = xmlMinidom.getString(xmldoc, 'Name')
-        self.order = xmldoc.getElementsByTagName('Order')[0].firstChild.data
+            self.id = xmlMinidom.getNaturalAttribute(xmldoc, 'Id')
+        self.name = xmlMinidom.getStringAttribute(xmldoc, 'Name')
+        self.order = xmldoc.attributes["Order"].firstChild.data
         if methodology_version is not None:
             self.methodology_version = methodology_version
         if parent_page is not None:
+#            print self.name + " is a child of " + parent_page.name
             self.parent = parent_page
+        self.save()
         # Pages
         for xml_child in xmldoc.childNodes:
-            if xml_child.tagName == 'Pages':
+            # Some nodes are text nodes (e.g. u'\n     ') I need to look just at ELEMENT_NODE
+            if xml_child.nodeType == Node.ELEMENT_NODE and xml_child.tagName == 'Pages':
                 xml_pages = xml_child
                 break
         for xml_page in xml_pages.childNodes:
-            if xml_page.tagName == 'Page':
+            if xml_page.nodeType == Node.ELEMENT_NODE and xml_page.tagName == 'Page':
                 p = Page()
                 p.from_xml(xml_page, None, self, insert)
         # Questions
-        xml_questions = xmldoc.getElementsByTagName('Questions')
-        for xml_question in xml_questions:
-            q = Question()
-            q.from_xml(xml_question, self, insert)
-        
-    def to_xml(self):
-        str_xml = "<Id>" + str(self.id) + "</Id>"
-        str_xml += "<Name>" + self.name + "</Name>"
-        str_xml += "<Order>" + str(self.order) + "</Order>"
-        str_xml += "<Pages>"
+        for xml_child in xmldoc.childNodes:
+            # Some nodes are text nodes (e.g. u'\n     ') I need to look just at ELEMENT_NODE
+            if xml_child.nodeType == Node.ELEMENT_NODE and xml_child.tagName == 'Questions':
+                xml_questions = xml_child
+                break
+        for xml_question in xml_questions.childNodes:
+            if xml_question.nodeType == Node.ELEMENT_NODE and xml_question.tagName == 'Question':
+                q = Question()
+                q.from_xml(xml_question, self, insert)
+        
+    def to_xml(self):
+        str_xml = "<Pages>"
         for page in self.page_set.all():
             str_xml += page.to_xml()
         str_xml += "</Pages>"
@@ -136,20 +134,26 @@
         for question in self.question_set.all():
             str_xml += question.to_xml()
         str_xml += "</Questions>"
-        return "<Page>" + str_xml + "</Page>"
-    
+        return '<Page Id="' + str(self.id) + '" Name="' + self.name + '" Order="' + str(self.order) + '">' + str_xml + "</Page>"
+
+    class Meta:
+        ordering = ['order']
+
 class QuestionType(models.Model):
     name = models.CharField(max_length=200)
     
     def from_xml(self, xmldoc, insert = True):
-        pass
-    
-    def to_xml(self):
-        return "<QuestionType><Id>" + str(self.id) + "</Id><Name>" + self.name + "</Name></QuestionType>"
+        if not insert:
+            self.id = xmlMinidom.getNaturalAttribute(xmldoc, 'Id')
+        self.name = xmlMinidom.getStringAttribute(xmldoc, 'Name')
+    
+    def to_xml(self):
+        return '<QuestionType Id="' + str(self.id) + '" Name="' + self.name + '"/>'
     
 class Question(models.Model):
     page = models.ForeignKey(Page)
     text = models.CharField(max_length=200)
+    order = models.IntegerField()
     eval_description = models.TextField(null=True,blank=True)
     eval_value = models.TextField(null=True,blank=True)
     question_type =  models.ForeignKey(QuestionType)
@@ -158,21 +162,45 @@
         return self.page.name + " - " + self.text
     
     def from_xml(self, xmldoc, page, insert = True):
-        pass
-    
-    def to_xml(self):
-        str_xml = "<Id>" + str(self.id) + "</Id>"
-        str_xml += "<Text>" + self.text + "</Text>"
-        str_xml += "<EvalDescription>" + ("" if self.eval_description is None else self.eval_description) + "</EvalDescription>"
+        if not insert:
+            self.id = xmlMinidom.getNaturalAttribute(xmldoc, 'Id')
+        self.text = xmlMinidom.getStringAttribute(xmldoc, 'Text')
+        self.order = xmlMinidom.getNaturalAttribute(xmldoc, 'Order')
+        #Do so that QuestionType default is 1
+        qt = QuestionType.objects.get(pk=1)
+        self.page = page
+        self.question_type = qt
+        self.save()
+        # Queries
+        xml_queries = xmldoc.getElementsByTagName('Query')
+        for xml_query in xml_queries:
+            q = Query()
+            q.from_xml(xml_query, self, insert)
+        # Choices
+        xml_choices = xmldoc.getElementsByTagName('Choice')
+        for xml_choice in xml_choices:
+            c = Choice()
+            c.from_xml(xml_choice, self, insert)
+        self.eval_description = xmlMinidom.getString(xmldoc, 'EvalDescription')
+        self.eval_value = xmlMinidom.getString(xmldoc, 'EvalValue')
+        
+    def to_xml(self):
+        str_xml = "<EvalDescription>" + ("" if self.eval_description is None else self.eval_description) + "</EvalDescription>"
         str_xml += "<EvalValue>" + ("" if self.eval_value is None else self.eval_value) + "</EvalValue>"
-        str_xml += self.question_type.to_xml()
+#         We do not use question_type at the moment as we have just one type
+#         str_xml += self.question_type.to_xml()
         str_xml += "<Queries>"
         for query in self.query_set.all():
             str_xml += query.to_xml()
+        str_xml += "</Queries>"
+        str_xml += "<Choices>"
         for choice in self.choice_set.all():
             str_xml += choice.to_xml()
-        str_xml += "</Queries>"
-        return "<Question>" + str_xml + "</Question>"
+        str_xml += "</Choices>"
+        return '<Question Id="' + str(self.id) + '" Text="' + self.text + '" Order="' + str(self.order) + '">' + str_xml + '</Question>'
+
+    class Meta:
+        ordering = ['order']
 
 class Query(models.Model):
     '''
@@ -183,15 +211,20 @@
     eval_site = models.CharField(max_length=2000)
     eval_site_exclude = models.CharField(max_length=2000)
     
-    def from_xml(self, xmldoc, insert = True):
-        pass
-    
-    def to_xml(self):
-        str_xml = "<Id>" + str(self.id) + "</Id>"
-        str_xml += "<EvalText>" + self.eval_text + "</EvalText>"
+    def from_xml(self, xmldoc, question, insert = True):
+        if not insert:
+            self.id = xmlMinidom.getNaturalAttribute(xmldoc, 'Id')
+        self.question = question
+        self.eval_text = xmlMinidom.getString(xmldoc, 'EvalText')
+        self.eval_site = xmlMinidom.getString(xmldoc, 'EvalSite')
+        self.eval_site_exclude = xmlMinidom.getString(xmldoc, 'EvalSiteExclude')
+        self.save()
+        
+    def to_xml(self):
+        str_xml = "<EvalText>" + self.eval_text + "</EvalText>"
         str_xml += "<EvalSite>" + self.eval_site + "</EvalSite>"
         str_xml += "<EvalSiteExclude>" + self.eval_site_exclude + "</EvalSiteExclude>"
-        return "<Query>" + str_xml + "</Query>"    
+        return '<Query Id="' + str(self.id) + '">' + str_xml + '</Query>'
 
 class Choice(models.Model):
     '''
@@ -201,15 +234,21 @@
     order = models.IntegerField()
     todo = models.CharField(max_length=2000)
     
-    def from_xml(self, xmldoc, insert = True):
-        pass
-    
-    def to_xml(self):
-        str_xml = "<Id>" + str(self.id) + "</Id>"
-        str_xml += "<Text>" + self.text + "</Text>"
-        str_xml += "<Order>" + str(self.order) + "</Order>"
-        str_xml += "<Todo>" + self.todo + "</Todo>"
-        return "<Choice>" + str_xml + "</Choice>"    
+    def from_xml(self, xmldoc, question, insert = True):
+        if not insert:
+            self.id = xmlMinidom.getNaturalAttribute(xmldoc, 'Id')
+        self.question = question
+        self.text = xmlMinidom.getStringAttribute(xmldoc, 'Text')
+        self.order = xmlMinidom.getNaturalAttribute(xmldoc, 'Order')
+        self.todo = xmlMinidom.getString(xmldoc, 'Todo')
+        self.save()
+    
+    def to_xml(self):
+        str_xml = "<Todo>" + self.todo + "</Todo>"
+        return '<Choice Id="' + str(self.id) + '" Text="' + self.text + '" Order="' + str(self.order) + '">' + str_xml + '</Choice>'
+
+    class Meta:
+        ordering = ['order']
 
 class WeightScenario(models.Model):
     name = models.CharField(max_length=200)
@@ -221,14 +260,11 @@
         pass
     
     def to_xml(self):
-        str_xml = "<Id>" + str(self.id) + "</Id>"
-        str_xml += "<Name>" + self.name + "</Name>"
-        str_xml += "<Active>" + str(self.active) + "</Active>"
-        str_xml += "<Weights>"
+        str_xml = "<Weights>"
         for weight in self.weight_set.all():
             str_xml += weight.to_xml()
         str_xml += "</Weights>"
-        return "<WeightScenario>" + str_xml + "</WeightScenario>"
+        return '<WeightScenario Id="' + str(self.id) + '" Name="' + self.name + '" Active="' + str(self.active) + '">' + str_xml + '</WeightScenario>'
 
 class Weight(models.Model):
     question = models.ForeignKey(Question)
@@ -245,4 +281,4 @@
         for weight in self.weight_set.all():
             str_xml += weight.to_xml()
         str_xml += "</Weights>"
-        return "<WeightScenario>" + str_xml + "</WeightScenario>"
+        return '<Weight Id="' + str(self.id) + '" Active="' + str(self.active) + '">' + str_xml + '</Weight>'